Skip to content

Commit a89fe41

Browse files
levibuzolicfacebook-github-bot
authored andcommitted
Map TextInput textContentType strings to Objective-C constants (#22611)
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
1 parent 35b6f86 commit a89fe41

File tree

2 files changed

+74
-3
lines changed

2 files changed

+74
-3
lines changed

Libraries/Text/TextInput/RCTBaseTextInputView.m

+59-3
Original file line numberDiff line numberDiff line change
@@ -141,9 +141,9 @@ - (void)setAttributedText:(NSAttributedString *)attributedText
141141

142142
[attributedTextCopy removeAttribute:RCTTextAttributesTagAttributeName
143143
range:NSMakeRange(0, attributedTextCopy.length)];
144-
144+
145145
textNeedsUpdate = ([self textOf:attributedTextCopy equals:backedTextInputViewTextCopy] == NO);
146-
146+
147147
if (eventLag == 0 && textNeedsUpdate) {
148148
UITextRange *selection = self.backedTextInputView.selectedTextRange;
149149
NSInteger oldTextLength = self.backedTextInputView.attributedText.string.length;
@@ -203,9 +203,65 @@ - (void)setTextContentType:(NSString *)type
203203
{
204204
#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_10_0
205205
if (@available(iOS 10.0, *)) {
206+
207+
static dispatch_once_t onceToken;
208+
static NSDictionary<NSString *, NSString *> *contentTypeMap;
209+
210+
dispatch_once(&onceToken, ^{
211+
contentTypeMap = @{@"none": @"",
212+
@"URL": UITextContentTypeURL,
213+
@"addressCity": UITextContentTypeAddressCity,
214+
@"addressCityAndState":UITextContentTypeAddressCityAndState,
215+
@"addressState": UITextContentTypeAddressState,
216+
@"countryName": UITextContentTypeCountryName,
217+
@"creditCardNumber": UITextContentTypeCreditCardNumber,
218+
@"emailAddress": UITextContentTypeEmailAddress,
219+
@"familyName": UITextContentTypeFamilyName,
220+
@"fullStreetAddress": UITextContentTypeFullStreetAddress,
221+
@"givenName": UITextContentTypeGivenName,
222+
@"jobTitle": UITextContentTypeJobTitle,
223+
@"location": UITextContentTypeLocation,
224+
@"middleName": UITextContentTypeMiddleName,
225+
@"name": UITextContentTypeName,
226+
@"namePrefix": UITextContentTypeNamePrefix,
227+
@"nameSuffix": UITextContentTypeNameSuffix,
228+
@"nickname": UITextContentTypeNickname,
229+
@"organizationName": UITextContentTypeOrganizationName,
230+
@"postalCode": UITextContentTypePostalCode,
231+
@"streetAddressLine1": UITextContentTypeStreetAddressLine1,
232+
@"streetAddressLine2": UITextContentTypeStreetAddressLine2,
233+
@"sublocality": UITextContentTypeSublocality,
234+
@"telephoneNumber": UITextContentTypeTelephoneNumber,
235+
};
236+
237+
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 110000 /* __IPHONE_11_0 */
238+
if (@available(iOS 11.0, *)) {
239+
NSDictionary<NSString *, NSString *> * iOS11extras = @{@"username": UITextContentTypeUsername,
240+
@"password": UITextContentTypePassword};
241+
242+
NSMutableDictionary<NSString *, NSString *> * iOS11baseMap = [contentTypeMap mutableCopy];
243+
[iOS11baseMap addEntriesFromDictionary:iOS11extras];
244+
245+
contentTypeMap = [iOS11baseMap copy];
246+
}
247+
#endif
248+
249+
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 120000 /* __IPHONE_12_0 */
250+
if (@available(iOS 12.0, *)) {
251+
NSDictionary<NSString *, NSString *> * iOS12extras = @{@"newPassword": UITextContentTypeNewPassword,
252+
@"oneTimeCode": UITextContentTypeOneTimeCode};
253+
254+
NSMutableDictionary<NSString *, NSString *> * iOS12baseMap = [contentTypeMap mutableCopy];
255+
[iOS12baseMap addEntriesFromDictionary:iOS12extras];
256+
257+
contentTypeMap = [iOS12baseMap copy];
258+
}
259+
#endif
260+
});
261+
206262
// Setting textContentType to an empty string will disable any
207263
// default behaviour, like the autofill bar for password inputs
208-
self.backedTextInputView.textContentType = [type isEqualToString:@"none"] ? @"" : type;
264+
self.backedTextInputView.textContentType = contentTypeMap[type] ?: type;
209265
}
210266
#endif
211267
}

RNTester/js/TextInputExample.ios.js

+15
Original file line numberDiff line numberDiff line change
@@ -1085,4 +1085,19 @@ exports.examples = [
10851085
);
10861086
},
10871087
},
1088+
{
1089+
title: 'Text Content Type',
1090+
render: function() {
1091+
return (
1092+
<View>
1093+
<WithLabel label="emailAddress">
1094+
<TextInput textContentType="emailAddress" style={styles.default} />
1095+
</WithLabel>
1096+
<WithLabel label="name">
1097+
<TextInput textContentType="name" style={styles.default} />
1098+
</WithLabel>
1099+
</View>
1100+
);
1101+
},
1102+
},
10881103
];

0 commit comments

Comments
 (0)