From 58def5a2e3559a06ddc086720ec78d35ad822c69 Mon Sep 17 00:00:00 2001 From: Dave Sibiski Date: Mon, 7 Sep 2015 20:53:01 -0400 Subject: [PATCH] [TextInput] Fixes 'AutoCorrect on Submit' bug Catches a spelling auto correction when the 'Return' key is pressed and makes sure that a `RCTTextEventTypeChange` event fires. - Doesn't increment the `nativeEventCount` as it doesn't need to match up with JS. - Extracts a few methods in `RCTTextFieldManager` to reduce duplication introduced. Resolves: https://github.com/facebook/react-native/issues/2552 --- Libraries/Text/RCTTextField.h | 1 + Libraries/Text/RCTTextField.m | 5 ++++ Libraries/Text/RCTTextFieldManager.m | 37 +++++++++++++++++++++++----- 3 files changed, 37 insertions(+), 6 deletions(-) diff --git a/Libraries/Text/RCTTextField.h b/Libraries/Text/RCTTextField.h index 0448dcfca8ca8f..1d66c26dbc4b28 100644 --- a/Libraries/Text/RCTTextField.h +++ b/Libraries/Text/RCTTextField.h @@ -32,5 +32,6 @@ - (void)textFieldDidChange; - (void)sendKeyValueForString:(NSString *)string; - (BOOL)textFieldShouldEndEditing:(RCTTextField *)textField; +- (void)sendChangeEvent; @end diff --git a/Libraries/Text/RCTTextField.m b/Libraries/Text/RCTTextField.m index 24b077baff106b..1c5a1e95edd663 100644 --- a/Libraries/Text/RCTTextField.m +++ b/Libraries/Text/RCTTextField.m @@ -168,6 +168,11 @@ - (BOOL)autoCorrect - (void)textFieldDidChange { _nativeEventCount++; + [self sendChangeEvent]; +} + +- (void)sendChangeEvent +{ [_eventDispatcher sendTextEventWithType:RCTTextEventTypeChange reactTag:self.reactTag text:self.text diff --git a/Libraries/Text/RCTTextFieldManager.m b/Libraries/Text/RCTTextFieldManager.m index f2ccf07f4616f3..cbe9e3f3b682b2 100644 --- a/Libraries/Text/RCTTextFieldManager.m +++ b/Libraries/Text/RCTTextFieldManager.m @@ -38,20 +38,28 @@ - (BOOL)textField:(RCTTextField *)textField shouldChangeCharactersInRange:(NSRan } if (textField.maxLength == nil || [string isEqualToString:@"\n"]) { // Make sure forms can be submitted via return + if (textField.autocorrectionType == UITextAutocorrectionTypeYes) { // If autoCorrect is on... + if (range.length > 0 && ![string isEqualToString:@""]) { // This catches an auto correction on submit. + textField.text = [self replaceText:textField.text.mutableCopy inRange:range withString:string]; + // Collapse selection at end of insert to match normal paste behavior + textField.selectedTextRange = [self textRangeForTextField:textField + withTextPositionOffset:(range.location + string.length)]; + [textField sendChangeEvent]; + return NO; + } + } return YES; } + NSUInteger allowedLength = textField.maxLength.integerValue - textField.text.length + range.length; if (string.length > allowedLength) { if (string.length > 1) { // Truncate the input string so the result is exactly maxLength NSString *limitedString = [string substringToIndex:allowedLength]; - NSMutableString *newString = textField.text.mutableCopy; - [newString replaceCharactersInRange:range withString:limitedString]; - textField.text = newString; + textField.text = [self replaceText:textField.text.mutableCopy inRange:range withString:limitedString]; // Collapse selection at end of insert to match normal paste behavior - UITextPosition *insertEnd = [textField positionFromPosition:textField.beginningOfDocument - offset:(range.location + allowedLength)]; - textField.selectedTextRange = [textField textRangeFromPosition:insertEnd toPosition:insertEnd]; + textField.selectedTextRange = [self textRangeForTextField:textField + withTextPositionOffset:(range.location + allowedLength)]; [textField textFieldDidChange]; } return NO; @@ -73,6 +81,23 @@ - (BOOL)textFieldShouldEndEditing:(RCTTextField *)textField return [textField textFieldShouldEndEditing:textField]; } +- (NSString *)replaceText:(NSMutableString *)originalString + inRange:(NSRange)range + withString:(NSString *)string +{ + NSMutableString *newString = originalString; + [newString replaceCharactersInRange:range withString:string]; + return newString; +} + +- (UITextRange *)textRangeForTextField:(UITextField *)textField + withTextPositionOffset:(NSUInteger)offset +{ + UITextPosition *insertEnd = [textField positionFromPosition:textField.beginningOfDocument + offset:offset]; + return [textField textRangeFromPosition:insertEnd toPosition:insertEnd]; +} + RCT_EXPORT_VIEW_PROPERTY(caretHidden, BOOL) RCT_EXPORT_VIEW_PROPERTY(autoCorrect, BOOL) RCT_REMAP_VIEW_PROPERTY(editable, enabled, BOOL)