| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124 |
- #import "BTUIKTextField.h"
- #import "BTUIKInputAccessoryToolbar.h"
- #import "BTUIKAppearance.h"
- #import "BTUIKViewUtil.h"
- @interface BTUIKTextField () <UITextFieldDelegate>
- @property (nonatomic, copy) NSString *previousText;
- @end
- @implementation BTUIKTextField
- - (instancetype)init {
- if (self = [super init]) {
- self.hideCaret = NO;
- if ([UIDevice currentDevice].systemVersion.intValue == 9) {
- [self addTarget:self action:@selector(iOS9_changed) forControlEvents:UIControlEventEditingChanged];
- self.delegate = self;
- }
- }
- return self;
- }
- - (void)setPlaceholder:(NSString *)placeholder {
- NSMutableAttributedString *mutablePlaceholder = [[NSMutableAttributedString alloc] initWithString:placeholder];
- [mutablePlaceholder beginEditing];
- [mutablePlaceholder addAttributes:@{NSForegroundColorAttributeName: [BTUIKAppearance sharedInstance].placeholderTextColor,
- NSFontAttributeName:[[BTUIKAppearance sharedInstance].font fontWithSize:UIFont.labelFontSize]}
- range:NSMakeRange(0, [mutablePlaceholder length])];
- [mutablePlaceholder endEditing];
-
- self.attributedPlaceholder = mutablePlaceholder;
- }
- - (void)iOS9_changed {
- // We only want to notify when this text field's text length has increased
- if (self.previousText.length >= self.text.length) {
- self.previousText = self.text;
- return;
- }
- self.previousText = self.text;
-
- NSString *insertedText = [self.text substringWithRange:NSMakeRange(self.previousText.length, self.text.length - self.previousText.length)];
-
- if ([self.editDelegate respondsToSelector:@selector(textField:willInsertText:)]) {
- // Sets _backspace = NO; in the BTUIKFormField or BTUIKFormField subclass
- [self.editDelegate textField:self willInsertText:insertedText];
- }
- self.previousText = self.text;
-
- if ([self.editDelegate respondsToSelector:@selector(textField:didInsertText:)]) {
- [self.editDelegate textField:self didInsertText:insertedText];
- }
- }
- - (BOOL)keyboardInputShouldDelete:(__unused UITextField *)textField {
- if ([self.editDelegate respondsToSelector:@selector(textFieldWillDeleteBackward:)]) {
- [self.editDelegate textFieldWillDeleteBackward:self];
- }
- BOOL shouldDelete = YES;
- if ([UITextField instancesRespondToSelector:_cmd]) {
- BOOL (*keyboardInputShouldDelete)(id, SEL, UITextField *) = (BOOL (*)(id, SEL, UITextField *))[UITextField instanceMethodForSelector:_cmd];
- if (keyboardInputShouldDelete) {
- shouldDelete = keyboardInputShouldDelete(self, _cmd, textField);
- }
- }
- BOOL isIos8 = ([[[UIDevice currentDevice] systemVersion] intValue] == 8);
- BOOL isLessThanIos8_3 = ([[[UIDevice currentDevice] systemVersion] floatValue] < 8.3f);
- // iOS 8.0-8.2 has a bug where deleteBackward is not called even when this method returns YES and the character is deleted
- // As a result, we do so manually but return NO in order to prevent UITextField from double-calling the delegate method
- // (textFieldDidDeleteBackwards:originalText:)
- if (isIos8 && isLessThanIos8_3) {
- [self deleteBackward];
- shouldDelete = NO;
- }
-
- return shouldDelete;
- }
- - (void)deleteBackward
- {
- BOOL shouldDismiss = [self.text length] == 0;
- NSString *originalText = self.text;
- [super deleteBackward];
- if (shouldDismiss) {
- if ([self.delegate respondsToSelector:@selector(textField:shouldChangeCharactersInRange:replacementString:)]) {
- [self.delegate textField:self shouldChangeCharactersInRange:NSMakeRange(0, 0) replacementString:@""];
- }
- }
- if ([self.editDelegate respondsToSelector:@selector(textFieldDidDeleteBackward:originalText:)]) {
- [self.editDelegate textFieldDidDeleteBackward:self originalText:originalText];
- }
- }
- - (void)insertText:(NSString *)text {
- if ([self.editDelegate respondsToSelector:@selector(textField:willInsertText:)]) {
- [self.editDelegate textField:self willInsertText:text];
- }
- [super insertText:text];
- if ([self.editDelegate respondsToSelector:@selector(textField:didInsertText:)]) {
- [self.editDelegate textField:self didInsertText:text];
- }
- }
- - (CGRect)caretRectForPosition:(UITextPosition *)position
- {
- if (self.hideCaret) {
- return CGRectZero;
- }
-
- return [super caretRectForPosition:position];
- }
- @end
|