Skip to content
This repository was archived by the owner on Oct 19, 2023. It is now read-only.

Commit 58c4e60

Browse files
committed
Merge pull request #7 from zydeco/master
Add changeable buttons property and (optionally) animate button changes
2 parents d23b34e + 156b0d8 commit 58c4e60

File tree

5 files changed

+138
-7
lines changed

5 files changed

+138
-7
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ Hope you enjoy it! Please Fork and send Pull Requests!
5757
##Contributors
5858
- [Rudd Fawcett (@ruddfawcett)] (https://github.com/ruddfawcett) - Creator (Version 1.0)
5959
- [Brandon Butler (@Hackmodford)] (https://github.com/Hackmodford) - Heavy Contributor (Version 1.1)
60+
- [Jesús A. Álvarez (@zydeco)] (https://github.com/zydeco) - Contributor
6061
6162
##License
6263

RFKeyboardToolbar/RFKeyboardToolbar.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99

1010
@interface RFKeyboardToolbar : UIView
1111

12+
@property (nonatomic, strong) NSArray *buttons;
13+
1214
+ (instancetype)toolbarViewWithButtons:(NSArray *)buttons;
1315

16+
- (void)setButtons:(NSArray *)buttons animated:(BOOL)animated;
17+
1418
@end

RFKeyboardToolbar/RFKeyboardToolbar.m

Lines changed: 68 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,6 @@ @interface RFKeyboardToolbar ()
1313
@property (nonatomic,strong) UIView *toolbarView;
1414
@property (nonatomic,strong) UIScrollView *scrollView;
1515
@property (nonatomic,strong) CALayer *topBorder;
16-
@property (nonatomic,strong) NSArray *buttonsToAdd;
1716

1817
@end
1918

@@ -26,7 +25,7 @@ + (instancetype)toolbarViewWithButtons:(NSArray *)buttons {
2625
- (id)initWithButtons:(NSArray*)buttons {
2726
self = [super initWithFrame:CGRectMake(0, 0, self.window.rootViewController.view.bounds.size.width, 40)];
2827
if (self) {
29-
_buttonsToAdd = buttons;
28+
_buttons = [buttons copy];
3029
self.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight;
3130
[self addSubview:[self inputAccessoryView]];
3231
}
@@ -62,12 +61,19 @@ - (UIScrollView*)fakeToolbar {
6261
_scrollView.showsHorizontalScrollIndicator = NO;
6362
_scrollView.contentInset = UIEdgeInsetsMake(6.0f, 0.0f, 8.0f, 6.0f);
6463

64+
[self addButtons];
65+
66+
return _scrollView;
67+
}
68+
69+
- (void)addButtons
70+
{
6571
NSUInteger index = 0;
6672
NSUInteger originX = 8;
6773

6874
CGRect originFrame;
6975

70-
for (RFToolbarButton *eachButton in _buttonsToAdd) {
76+
for (RFToolbarButton *eachButton in _buttons) {
7177
originFrame = CGRectMake(originX, 0, eachButton.frame.size.width, eachButton.frame.size.height);
7278
eachButton.frame = originFrame;
7379

@@ -80,8 +86,66 @@ - (UIScrollView*)fakeToolbar {
8086
CGSize contentSize = _scrollView.contentSize;
8187
contentSize.width = originX - 8;
8288
_scrollView.contentSize = contentSize;
89+
}
90+
91+
- (void)setButtons:(NSArray*)buttons
92+
{
93+
[_buttons makeObjectsPerformSelector:@selector(removeFromSuperview)];
94+
_buttons = [buttons copy];
95+
[self addButtons];
96+
}
97+
98+
- (void)setButtons:(NSArray *)buttons animated:(BOOL)animated
99+
{
100+
if (animated == NO)
101+
{
102+
self.buttons = buttons;
103+
return;
104+
}
83105

84-
return _scrollView;
106+
NSMutableSet *removeButtons = [NSMutableSet setWithArray:_buttons];
107+
[removeButtons minusSet:[NSSet setWithArray:buttons]];
108+
NSMutableSet *addButtons = [NSMutableSet setWithArray:buttons];
109+
[addButtons minusSet:[NSSet setWithArray:_buttons]];
110+
_buttons = [buttons copy];
111+
112+
// calculate end frames
113+
NSUInteger originX = 8;
114+
NSUInteger index = 0;
115+
NSMutableArray *buttonFrames = [NSMutableArray arrayWithCapacity:_buttons.count];
116+
for (RFToolbarButton *button in _buttons) {
117+
CGRect frame = CGRectMake(originX, 0, button.frame.size.width, button.frame.size.height);
118+
[buttonFrames addObject:[NSValue valueWithCGRect:frame]];
119+
120+
originX += button.bounds.size.width + 8;
121+
index++;
122+
}
123+
124+
CGSize contentSize = _scrollView.contentSize;
125+
contentSize.width = originX - 8;
126+
if (contentSize.width > _scrollView.contentSize.width)
127+
_scrollView.contentSize = contentSize;
128+
129+
// make added buttons appear from the right
130+
[addButtons enumerateObjectsUsingBlock:^(RFToolbarButton *button, BOOL *stop) {
131+
button.frame = CGRectMake(originX, 0, button.frame.size.width, button.frame.size.height);
132+
[_scrollView addSubview:button];
133+
}];
134+
135+
// animate
136+
[UIView animateWithDuration:0.2 animations:^{
137+
[removeButtons enumerateObjectsUsingBlock:^(RFToolbarButton *button, BOOL *stop) {
138+
button.alpha = 0;
139+
}];
140+
141+
[_buttons enumerateObjectsUsingBlock:^(RFToolbarButton *button, NSUInteger idx, BOOL *stop) {
142+
button.frame = [buttonFrames[idx] CGRectValue];
143+
}];
144+
145+
_scrollView.contentSize = contentSize;
146+
} completion:^(BOOL finished) {
147+
[removeButtons makeObjectsPerformSelector:@selector(removeFromSuperview)];
148+
}];
85149
}
86150

87151
@end

RFKeyboardToolbarDemo/RFKeyboardToolbar/ViewController.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,6 @@
88

99
#import <UIKit/UIKit.h>
1010

11-
@interface ViewController : UIViewController
11+
@interface ViewController : UIViewController <UITextViewDelegate>
1212

1313
@end

RFKeyboardToolbarDemo/RFKeyboardToolbar/ViewController.m

Lines changed: 64 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,29 @@ @interface ViewController ()
1616

1717
@end
1818

19+
@implementation UITextView (InsertWord)
20+
21+
- (void)insertWord:(NSString*)word
22+
{
23+
// insert a word into the field, adding a space before and/or after it as necessary
24+
NSCharacterSet *whitespace = [NSCharacterSet whitespaceAndNewlineCharacterSet];
25+
NSRange selectedRange = self.selectedRange;
26+
NSString *text = self.text;
27+
BOOL hasSpaceBefore = selectedRange.location == 0 || [whitespace characterIsMember:[text characterAtIndex:selectedRange.location-1]];
28+
BOOL hasSpaceAfter = selectedRange.location+selectedRange.length == text.length || [whitespace characterIsMember:[text characterAtIndex:selectedRange.location+selectedRange.length]];
29+
30+
NSMutableString *wordText = word.mutableCopy;
31+
if (!hasSpaceBefore) [wordText insertString:@" " atIndex:0];
32+
if (!hasSpaceAfter) [wordText appendString:@" "];
33+
[self insertText:wordText];
34+
}
35+
36+
@end
37+
1938
@implementation ViewController
39+
{
40+
RFKeyboardToolbar *keyboardToolbar;
41+
}
2042

2143
- (void)viewDidLoad
2244
{
@@ -32,9 +54,49 @@ - (void)viewDidLoad
3254
[_textView insertText:@"You pressed a button!"];
3355
} forControlEvents:UIControlEventTouchUpInside];
3456

35-
_textView.inputAccessoryView = [RFKeyboardToolbar toolbarViewWithButtons:@[exampleButton]];
36-
57+
keyboardToolbar = [RFKeyboardToolbar toolbarViewWithButtons:@[exampleButton]];
58+
_textView.inputAccessoryView = keyboardToolbar;
59+
_textView.delegate = self;
60+
3761
[self.view addSubview:_textView];
3862
}
3963

64+
- (void)textViewDidChange:(UITextView *)textView
65+
{
66+
// count words
67+
NSArray *allWords = [textView.text.lowercaseString componentsSeparatedByCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
68+
NSCountedSet *words = [NSCountedSet new];
69+
for (__strong NSString *word in allWords) {
70+
word = [word stringByTrimmingCharactersInSet:[NSCharacterSet punctuationCharacterSet]];
71+
if (word.length == 0) continue;
72+
[words addObject:word];
73+
}
74+
75+
// dictionary of existing words => buttons
76+
NSDictionary *oldButtons = [NSDictionary dictionaryWithObjects:keyboardToolbar.buttons forKeys:[keyboardToolbar.buttons valueForKey:@"title"]];
77+
78+
// create new buttons
79+
NSMutableArray *newButtons = [NSMutableArray arrayWithCapacity:words.count];
80+
for (NSString *word in words) {
81+
// create or reuse button
82+
RFToolbarButton *button = oldButtons[word];
83+
if (button == nil) {
84+
button = [RFToolbarButton buttonWithTitle:word];
85+
[button addEventHandler:^{
86+
[_textView insertWord:word];
87+
} forControlEvents:UIControlEventTouchUpInside];
88+
}
89+
[newButtons addObject:button];
90+
}
91+
92+
// sort by frequency and alphabetically
93+
[newButtons sortUsingComparator:^NSComparisonResult(id obj1, id obj2) {
94+
NSUInteger count1 = [words countForObject:[obj1 title]];
95+
NSUInteger count2 = [words countForObject:[obj2 title]];
96+
if (count1 == count2) return [[obj1 title] compare:[obj2 title]];
97+
return count1 > count2 ? NSOrderedAscending : NSOrderedDescending;
98+
}];
99+
[keyboardToolbar setButtons:newButtons animated:YES];
100+
}
101+
40102
@end

0 commit comments

Comments
 (0)