Support `<TextInput keyboardType="numeric" returnKeyType="done" />` on iOS
Summary: Standard only-numeric (number pad) keyboard on iOS does not have any "Done" or "Enter" button, and this is often very badly hurt user experience. Usually it can be solved by implementing custom `inputAccessoryView`, but RN does not have built-in support for customizing it. So, this commit introduced limited support only for "Done" button (returnKeyType="done") and it should suite very well for the vast majority of use cases. This is highly requested feature, see more details here: https://github.com/facebook/react-native/issues/1190 Reviewed By: mmmulani Differential Revision: D5268020 fbshipit-source-id: 90bd5bffac6aaa1fb7c5c2ac539b35b04d45918f
This commit is contained in:
parent
1081b21f3e
commit
2b1795c5ad
|
@ -18,5 +18,6 @@
|
|||
@property (nonatomic, assign, readonly) BOOL textWasPasted;
|
||||
@property (nonatomic, strong, nullable) UIFont *font;
|
||||
@property (nonatomic, assign) UIEdgeInsets textContainerInset;
|
||||
@property (nonatomic, strong, nullable) UIView *inputAccessoryView;
|
||||
|
||||
@end
|
||||
|
|
|
@ -155,4 +155,64 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithFrame:(CGRect)frame)
|
|||
[self.backedTextInputView reactFocusIfNeeded];
|
||||
}
|
||||
|
||||
#pragma mark - Custom Input Accessory View
|
||||
|
||||
- (void)didSetProps:(NSArray<NSString *> *)changedProps
|
||||
{
|
||||
[self invalidateInputAccessoryView];
|
||||
}
|
||||
|
||||
- (void)invalidateInputAccessoryView
|
||||
{
|
||||
#if !TARGET_OS_TV
|
||||
UIView<RCTBackedTextInputViewProtocol> *textInputView = self.backedTextInputView;
|
||||
UIKeyboardType keyboardType = textInputView.keyboardType;
|
||||
|
||||
// These keyboard types (all are number pads) don't have a "Done" button by default,
|
||||
// so we create an `inputAccessoryView` with this button for them.
|
||||
BOOL shouldHaveInputAccesoryView =
|
||||
(
|
||||
keyboardType == UIKeyboardTypeNumberPad ||
|
||||
keyboardType == UIKeyboardTypePhonePad ||
|
||||
keyboardType == UIKeyboardTypeDecimalPad ||
|
||||
keyboardType == UIKeyboardTypeASCIICapableNumberPad
|
||||
) &&
|
||||
textInputView.returnKeyType == UIReturnKeyDone;
|
||||
|
||||
BOOL hasInputAccesoryView = textInputView.inputAccessoryView != nil;
|
||||
|
||||
if (hasInputAccesoryView == shouldHaveInputAccesoryView) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (shouldHaveInputAccesoryView) {
|
||||
UIToolbar *toolbarView = [[UIToolbar alloc] init];
|
||||
[toolbarView sizeToFit];
|
||||
UIBarButtonItem *flexibleSpace =
|
||||
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
|
||||
target:nil
|
||||
action:nil];
|
||||
UIBarButtonItem *doneButton =
|
||||
[[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
|
||||
target:self
|
||||
action:@selector(handleInputAccessoryDoneButton)];
|
||||
toolbarView.items = @[flexibleSpace, doneButton];
|
||||
textInputView.inputAccessoryView = toolbarView;
|
||||
}
|
||||
else {
|
||||
textInputView.inputAccessoryView = nil;
|
||||
}
|
||||
|
||||
// We have to call `reloadInputViews` for focused text inputs to update an accessory view.
|
||||
if (textInputView.isFirstResponder) {
|
||||
[textInputView reloadInputViews];
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void)handleInputAccessoryDoneButton
|
||||
{
|
||||
[self.backedTextInputView endEditing:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -239,6 +239,7 @@ class BlurOnSubmitExample extends React.Component {
|
|||
ref="4"
|
||||
style={styles.default}
|
||||
keyboardType="numeric"
|
||||
returnKeyType="done"
|
||||
placeholder="blurOnSubmit = false"
|
||||
blurOnSubmit={false}
|
||||
onSubmitEditing={() => this.focusNextField('5')}
|
||||
|
|
Loading…
Reference in New Issue