-
Notifications
You must be signed in to change notification settings - Fork 17
Expand file tree
/
Copy pathASDViewController.m
More file actions
190 lines (162 loc) · 7.78 KB
/
ASDViewController.m
File metadata and controls
190 lines (162 loc) · 7.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
//
// ASDViewController.m
// AttributedStringDemo
//
// Created by Olivier Halligon on 13/08/2014.
// Copyright (c) 2014 AliSoftware. All rights reserved.
//
#import "ASDViewController.h"
#import <OHAttributedStringAdditions/OHAttributedStringAdditions.h>
@interface ASDViewController () <UISearchBarDelegate>
@property (weak, nonatomic) IBOutlet UITextView* textView;
@property (weak, nonatomic) IBOutlet NSLayoutConstraint* bottomDistance;
@property (weak, nonatomic) IBOutlet UILabel *footerLabel;
@end
@implementation ASDViewController
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
self.textView.attributedText = [self originalString];
NSMutableAttributedString* mas = [self.footerLabel.attributedText mutableCopy];
NSRange range = NSMakeRange(10, 20);
[mas setURL:[NSURL URLWithString:@"https://github.com/AliSoftware/OHAttributedStringAdditions/wiki"] range:range];
[mas setTextColor:[UIColor blueColor] range:range];
[mas setTextUnderlined:YES range:range];
self.footerLabel.attributedText = [mas copy];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(keyboardAnimation:)
name:UIKeyboardWillChangeFrameNotification
object:nil];
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
- (NSAttributedString*)originalString
{
static NSAttributedString* originalString;
static dispatch_once_t onceToken;
#define LIST_TITLE @"Easily get, set or change"
dispatch_once(&onceToken, ^{
NSString* html = @""
"Hello <b>you</b>!<br>"
"<br>"
"<p>This is <a href='https://github.com/AliSoftware/OHAttributedStringAdditions'>OHAttributedStringAdditions</a>,"
" a cool <i>category</i> that lets you <font color='red'>manipulate</font> <tt>NSAttributedString</tt>"
" with nicer methods<sup>(1)</sup>.</p>"
"<p>For example you can change the <font face='Zapfino'>font</font>, make text"
" <b>bold</b>, <i>italics</i> or <u>underlined</u>, …</p>"
"<p style='text-align:center'>Amazing, isn't it?</p>"
"<p style='text-indent:30px;'>You can even <font color='#da0'>indent</font> the first line of your"
" paragraphs to make nice text layouts, justify paragraphs, and a lot more!</p>"
"<p><sup>(1)</sup>" LIST_TITLE ":<ul>"
"<li>Fonts : <tt>setFont:range:</tt></li>"
"<li>Colors : <tt>setTextColor:range:</tt></li>"
"<li>Style : <tt>setTextBold:range:</tt>, <tt>setTextUnderlined:range:</tt>, …</li>"
"<li>URLs : <tt>setURL:range:</tt></li>"
"<li>Paragraph style (indentation, text alignment, …)</li>"
"<li>And much more</li>"
"</ul></p>"
"<p style='text-indent:30px'><font color='gray'>Note: Part of this attributed string is created"
" by using <font color='#00c'>basic HTML code</font>, and some other attribues"
" are <font color='#00c'>set by code</font> to demonstrate the usage of"
" <tt>OHAttributedStringAdditions</tt> methods.</font></p>"
"<i><center>Don't hesitate to try the search field at the top of the screen."
" Searched text will be highlighted dynamically!</center></i>";
NSMutableAttributedString* str = [NSMutableAttributedString attributedStringWithHTML:html];
// Scale the font size by +50%
[str enumerateFontsInRange:NSMakeRange(0,str.length)
includeUndefined:YES
usingBlock:^(UIFont *font, NSRange range, BOOL *stop)
{
if (!font) font = [NSAttributedString defaultFont];
UIFont* newFont = [font fontWithSize:font.pointSize * 1.5f] ;
[str setFont:newFont range:range];
}];
[str setTextUnderlined:YES range:[str.string rangeOfString:@"Amazing"]];
NSRange listTitleRange = [str.string rangeOfString:LIST_TITLE];
[str setTextColor:[UIColor colorWithRed:0 green:0.5 blue:0 alpha:1.] range:listTitleRange];
[str setTextUnderlineStyle:NSUnderlineStyleThick|NSUnderlinePatternDot range:listTitleRange];
[str changeParagraphStylesInRange:NSMakeRange(0, str.length)
withBlock:^(NSMutableParagraphStyle* style, NSRange aRange)
{
// For example, justify only paragraphs that have a indentation
if (style.firstLineHeadIndent > 0)
{
style.alignment = NSTextAlignmentJustified;
}
}];
originalString = [str copy];
});
return originalString;
}
// MARK: Tap on a links
// Links in TextView are already supported by UITextViewDelegate
- (BOOL)textView:(UITextView *)textView shouldInteractWithURL:(NSURL *)URL inRange:(NSRange)characterRange
{
// Intercept taps on links to display an alert instead of opening it in Safari
[[[UIAlertView alloc] initWithTitle:@"URL Tapped"
message:URL.absoluteString
delegate:nil cancelButtonTitle:@"OK" otherButtonTitles:nil] show];
return NO;
}
// Links on UILabel have to use UITapGestureRecognizer (here added via the XIB)
- (IBAction)tapOnFooter:(UITapGestureRecognizer *)tapGR
{
if (tapGR.state == UIGestureRecognizerStateEnded)
{
CGPoint tapPoint = [tapGR locationInView:self.footerLabel];
NSUInteger pos = [self.footerLabel characterIndexAtPoint:tapPoint];
if (pos != NSNotFound)
{
NSLog(@"POS: %zi", pos);
NSURL* urlTapped = [self.footerLabel.attributedText URLAtIndex:pos effectiveRange:NULL];
if (urlTapped) [[UIApplication sharedApplication] openURL:urlTapped];
}
}
}
// MARK: Text Search
- (void)searchBar:(UISearchBar *)searchBar textDidChange:(NSString *)searchText
{
if (searchText.length > 0)
{
NSMutableAttributedString* highlightedString = [[self originalString] mutableCopy];
NSRegularExpressionOptions options = NSRegularExpressionCaseInsensitive|NSRegularExpressionIgnoreMetacharacters;
NSRegularExpression* regex = [NSRegularExpression regularExpressionWithPattern:searchText
options:options
error:NULL];
[regex enumerateMatchesInString:self.textView.text
options:0
range:NSMakeRange(0, self.textView.text.length)
usingBlock:^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop)
{
[highlightedString setTextBackgroundColor:[UIColor yellowColor] range:result.range];
}];
self.textView.attributedText = highlightedString;
}
else
{
// Reset to unhighlighted string
self.textView.attributedText = [self originalString];
}
}
- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar
{
[searchBar resignFirstResponder];
}
-(void)searchBarCancelButtonClicked:(UISearchBar *)searchBar
{
self.textView.attributedText = [self originalString];
[searchBar resignFirstResponder];
}
- (void)keyboardAnimation:(NSNotification*)notif
{
NSTimeInterval animDuration = [notif.userInfo[UIKeyboardAnimationDurationUserInfoKey] doubleValue];
CGRect endFrame = [notif.userInfo[UIKeyboardFrameEndUserInfoKey] CGRectValue];
self.bottomDistance.constant = self.view.window.bounds.size.height - endFrame.origin.y;
[UIView animateWithDuration:animDuration animations:^{
[self.textView layoutIfNeeded];
}];
}
@end