-
Notifications
You must be signed in to change notification settings - Fork 0
/
TaggableTextView.m
139 lines (117 loc) · 3.95 KB
/
TaggableTextView.m
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
//
// TaggableTextView.m
// tagg
//
// Created by Deep Patel on 3/5/14.
// Copyright (c) 2014 Deep Patel. All rights reserved.
//
#import "TaggableTextView.h"
@implementation TaggableTextView
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
[self setDelegate:self];
self.tagPrefix = @"@";
self.tagSource = nil;
self.tableView.rowHeight = 40.0;
self.tableViewClass = [UITableView class];
self.textFieldClass = [UITextField class];
}
return self;
}
- (void)makeTaggable {
_tableView = [[_tableViewClass alloc] initWithFrame: [[UIScreen mainScreen] bounds]];
_tableView.delegate = self;
_tableView.dataSource = self;
[[self superview] addSubview:_tableView];
_tagField = [[_textFieldClass alloc] init];
_tagField.delegate = self;
[self.superview addSubview:_tagField];
if (_tagSource)
_cachedMode = YES;
else
_cachedMode = NO;
[self exitTaggingMode];
}
- (void) refreshVisibleRows {
_visibleRows = [[NSMutableArray alloc] init];
NSString *temp = [[_tagField.text lowercaseString] substringFromIndex: 1];
if (!_cachedMode) {
_tagSource = [self tagsForQuery: _tagField.text];
}
if ([_tagField.text isEqualToString: _tagPrefix] || (!_cachedMode))
{
[_tagSource enumerateObjectsUsingBlock:^(id x, NSUInteger index, BOOL *stop){
[_visibleRows addObject: [NSNumber numberWithInteger:index]];
}];
} else {
[_tagSource enumerateObjectsUsingBlock:^(id x, NSUInteger index, BOOL *stop){
if ([[x lowercaseString] rangeOfString: temp].location != NSNotFound)
{
[_visibleRows addObject: [NSNumber numberWithInteger:index]];
}
}];
}
[_tableView reloadData];
}
- (void)textViewDidChange:(TaggableTextView *)textView
{
if([textView.text hasSuffix: _tagPrefix]){
[self enterTaggingMode];
}
}
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string{
if(range.location == 0){
self.text = [self.text substringToIndex: self.text.length - 1];
[self exitTaggingMode];
} else {
_tagField.text = [_tagField.text stringByReplacingCharactersInRange:range withString:string];
[self refreshVisibleRows];
}
return false;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_visibleRows count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
id cell = [tableView dequeueReusableHeaderFooterViewWithIdentifier:@""];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@""];
}
[[cell textLabel] setText: [_tagSource objectAtIndex: [[_visibleRows objectAtIndex: indexPath.row] integerValue]]];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
[self exitTaggingMode];
[self setText: [self.text stringByAppendingString: [tableView cellForRowAtIndexPath:indexPath].textLabel.text]];
[self didTagItemAt: [_visibleRows objectAtIndex: indexPath.row]];
}
-(void) enterTaggingMode{
[_tagField setHidden:NO];
[_tableView setHidden:NO];
[_tagField becomeFirstResponder];
[self setHidden:YES];
_tagField.text = _tagPrefix;
[self refreshVisibleRows];
}
-(void) exitTaggingMode{
[_tagField setHidden:YES];
[_tableView setHidden:YES];
[self becomeFirstResponder];
[self setHidden:NO];
}
-(void) didTagItemAt: (NSNumber*) i {
}
-(NSArray*) tagsForQuery: (NSString*) query {
return @[@"This should not happen"];
}
/*
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
// Drawing code
}
*/
@end