Skip to content

Commit

Permalink
Map TextInput textContentType strings to Objective-C constants (#22611)
Browse files Browse the repository at this point in the history
Summary:
This is an updated version of #22579 which uses compile conditionals to prevent `use of undeclared identifier` errors when compiling on older versions of Xcode.

--------

Currently the only `textContentType` values that work are: `username`, `password`, `location`, `name` and `nickname`. This is due to the strings provided by React Native not matching up with the underlying string constants used in iOS (with the exception of the aforementioned types). Issue #22578 has more detail examples/explanation.
Pull Request resolved: #22611

Differential Revision: D13460949

Pulled By: cpojer

fbshipit-source-id: e6d1108422b850ebc3aea05693ed05118b77b5de
  • Loading branch information
levibuzolic authored and facebook-github-bot committed Feb 20, 2019
1 parent 35b6f86 commit a89fe41
Show file tree
Hide file tree
Showing 2 changed files with 74 additions and 3 deletions.
62 changes: 59 additions & 3 deletions Libraries/Text/TextInput/RCTBaseTextInputView.m
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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<NSString *, NSString *> *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<NSString *, NSString *> * iOS11extras = @{@"username": UITextContentTypeUsername,
@"password": UITextContentTypePassword};

NSMutableDictionary<NSString *, NSString *> * 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<NSString *, NSString *> * iOS12extras = @{@"newPassword": UITextContentTypeNewPassword,
@"oneTimeCode": UITextContentTypeOneTimeCode};

NSMutableDictionary<NSString *, NSString *> * 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
}
Expand Down
15 changes: 15 additions & 0 deletions RNTester/js/TextInputExample.ios.js
Original file line number Diff line number Diff line change
Expand Up @@ -1085,4 +1085,19 @@ exports.examples = [
);
},
},
{
title: 'Text Content Type',
render: function() {
return (
<View>
<WithLabel label="emailAddress">
<TextInput textContentType="emailAddress" style={styles.default} />
</WithLabel>
<WithLabel label="name">
<TextInput textContentType="name" style={styles.default} />
</WithLabel>
</View>
);
},
},
];

0 comments on commit a89fe41

Please sign in to comment.