markohlebar / BIND

Data Binding and MVVM for iOS
MIT License
355 stars 48 forks source link

UITextField value while typing (UIControlEventEditingChanged) #9

Closed benvium closed 9 years ago

benvium commented 9 years ago

Is there a way to get the bindings to work on a UITextField while the user types? With a simple example I've been unable to get the binding to fire when typing into the UITextField. It works find if I actually set the .text value manually.

UILabel *title = [UILabel new];
title.text = @"empty title";

UITextField field = [[UITextField alloc] init];
field.text = @"empty field";
//..
BIND(item, value, <>, field, text);

[BINDO(field, text) observe:^(id observable, id value) {
            NSLog(@"value=%@", value); // any way to have this called as I type?
}];

//.. 
field.text = @"this works though";

Previously to experimenting with BIND I'd use addTarget:forControlEvents:UIControlEventEditingChanged to trigger a selector as the user types.

A more 'BINDy' way to do this would be great. Any ideas?

benvium commented 9 years ago

Aha. Looking through your source code I saw how you'd wrapped UIButton. I did the same with UITextField's UIControlEventEditingChanged and it worked!

Here's my code:

static NSString *const BNDBindingEditingChangedKeyPath = @"onEditingChanged";

@interface UITextField (BNDBinding)
@property (nonatomic) NSString *onEditingChanged;
@end
#import "UITextField+BNDBinding.h"
#import "BNDSpecialKeyPathHandling.h"

@implementation UITextField (BNDBinding)
- (void)handleSpecialKeyPath:(NSString *)keyPath {
    if ([keyPath isEqual:BNDBindingEditingChangedKeyPath]) {
        [self addTarget:self
                 action:@selector(setOnEditingChanged:)
       forControlEvents:UIControlEventEditingChanged];
    }
}

- (void)setOnEditingChanged:(NSString *)string {
    [self didChangeValueForKey:BNDBindingEditingChangedKeyPath];
}

- (NSString *)onEditingChanged {
    return self.text;
}
@end
// usage
[BIND(self.field, onEditingChanged, ->, item, value) observe:^(UITextField *observable, NSString *value) {                    
    NSLog(@"%@", value);
}]

output:

2015-04-12 15:02:24.571 bindTest[20232:3447740] fish 
2015-04-12 15:02:24.700 bindTest[20232:3447740] fish a
2015-04-12 15:02:24.811 bindTest[20232:3447740] fish an
2015-04-12 15:02:24.947 bindTest[20232:3447740] fish and
2015-04-12 15:02:25.062 bindTest[20232:3447740] fish and 
2015-04-12 15:02:25.230 bindTest[20232:3447740] fish and c
2015-04-12 15:02:25.263 bindTest[20232:3447740] fish and ch
2015-04-12 15:02:25.346 bindTest[20232:3447740] fish and chi
2015-04-12 15:02:25.388 bindTest[20232:3447740] fish and chip
2015-04-12 15:02:25.501 bindTest[20232:3447740] fish and chips
markohlebar commented 9 years ago

@benvium good stuff, can you assemble a PR?