diff --git a/Libraries/Text/TextInput/RCTBaseTextInputView.m b/Libraries/Text/TextInput/RCTBaseTextInputView.m index c1c3b00c850568..1ac2dd18edc570 100644 --- a/Libraries/Text/TextInput/RCTBaseTextInputView.m +++ b/Libraries/Text/TextInput/RCTBaseTextInputView.m @@ -141,9 +141,9 @@ - (void)setAttributedText:(NSAttributedString *)attributedText [attributedTextCopy removeAttribute:RCTTextAttributesTagAttributeName range:NSMakeRange(0, attributedTextCopy.length)]; - + textNeedsUpdate = ([self textOf:attributedTextCopy equals:backedTextInputViewTextCopy] == NO); - + if (eventLag == 0 && textNeedsUpdate) { UITextRange *selection = self.backedTextInputView.selectedTextRange; NSInteger oldTextLength = self.backedTextInputView.attributedText.string.length; @@ -203,9 +203,65 @@ - (void)setTextContentType:(NSString *)type { #if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0 if (@available(iOS 10.0, *)) { + + static dispatch_once_t onceToken; + static NSDictionary *contentTypeMap; + + dispatch_once(&onceToken, ^{ + contentTypeMap = @{@"none": @"", + @"URL": UITextContentTypeURL, + @"addressCity": UITextContentTypeAddressCity, + @"addressCityAndState":UITextContentTypeAddressCityAndState, + @"addressState": UITextContentTypeAddressState, + @"countryName": UITextContentTypeCountryName, + @"creditCardNumber": UITextContentTypeCreditCardNumber, + @"emailAddress": UITextContentTypeEmailAddress, + @"familyName": UITextContentTypeFamilyName, + @"fullStreetAddress": UITextContentTypeFullStreetAddress, + @"givenName": UITextContentTypeGivenName, + @"jobTitle": UITextContentTypeJobTitle, + @"location": UITextContentTypeLocation, + @"middleName": UITextContentTypeMiddleName, + @"name": UITextContentTypeName, + @"namePrefix": UITextContentTypeNamePrefix, + @"nameSuffix": UITextContentTypeNameSuffix, + @"nickname": UITextContentTypeNickname, + @"organizationName": UITextContentTypeOrganizationName, + @"postalCode": UITextContentTypePostalCode, + @"streetAddressLine1": UITextContentTypeStreetAddressLine1, + @"streetAddressLine2": UITextContentTypeStreetAddressLine2, + @"sublocality": UITextContentTypeSublocality, + @"telephoneNumber": UITextContentTypeTelephoneNumber, + }; + + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */ + if (@available(iOS 11.0, *)) { + NSDictionary * iOS11extras = @{@"username": UITextContentTypeUsername, + @"password": UITextContentTypePassword}; + + NSMutableDictionary * iOS11baseMap = [contentTypeMap mutableCopy]; + [iOS11baseMap addEntriesFromDictionary:iOS11extras]; + + contentTypeMap = [iOS11baseMap copy]; + } + #endif + + #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 /* __IPHONE_12_0 */ + if (@available(iOS 12.0, *)) { + NSDictionary * iOS12extras = @{@"newPassword": UITextContentTypeNewPassword, + @"oneTimeCode": UITextContentTypeOneTimeCode}; + + NSMutableDictionary * iOS12baseMap = [contentTypeMap mutableCopy]; + [iOS12baseMap addEntriesFromDictionary:iOS12extras]; + + contentTypeMap = [iOS12baseMap copy]; + } + #endif + }); + // Setting textContentType to an empty string will disable any // default behaviour, like the autofill bar for password inputs - self.backedTextInputView.textContentType = [type isEqualToString:@"none"] ? @"" : type; + self.backedTextInputView.textContentType = contentTypeMap[type] ?: type; } #endif } diff --git a/RNTester/js/TextInputExample.ios.js b/RNTester/js/TextInputExample.ios.js index b7a61032e98c6a..5529db69a064ca 100644 --- a/RNTester/js/TextInputExample.ios.js +++ b/RNTester/js/TextInputExample.ios.js @@ -1085,4 +1085,19 @@ exports.examples = [ ); }, }, + { + title: 'Text Content Type', + render: function() { + return ( + + + + + + + + + ); + }, + }, ];