From e0664d4853ace55bd18e1ad849fa8f64cfc88c0e Mon Sep 17 00:00:00 2001 From: LongCat is Looong <31859944+LongCatIsLooong@users.noreply.github.com> Date: Fri, 25 Jun 2021 15:52:44 -0700 Subject: [PATCH 1/2] [iOS TextInput] Disables system keyboard for TextInputType.none Continuation of https://github.com/flutter/engine/pull/26773 --- .../Source/FlutterTextInputPlugin.mm | 27 +++++++++++++++++++ .../Source/FlutterTextInputPluginTest.m | 14 ++++++++++ 2 files changed, 41 insertions(+) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm index 038a40d378c63..9f641acf02017 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm @@ -55,6 +55,14 @@ #pragma mark - Static Functions +// "TextInputType.none" is a made-up input type that's typically +// used when there's an in-app virtual keyboard. If +// "TextInputType.none" is specified, disable the system +// keyboard. +static BOOL shouldShowSystemKeyboard(NSDictionary* type) { + NSString* inputType = type[@"name"]; + return ![inputType isEqualToString:@"TextInputType.none"]; +} static UIKeyboardType ToUIKeyboardType(NSDictionary* type) { NSString* inputType = type[@"name"]; if ([inputType isEqualToString:@"TextInputType.address"]) @@ -516,7 +524,12 @@ @implementation FlutterTextInputView { int _textInputClient; const char* _selectionAffinity; FlutterTextRange* _selectedTextRange; + UIInputViewController* _inputViewcController; CGRect _cachedFirstRect; + // Whether to show the system keyboard when this view + // becomes the first responder. Typically set to false + // when the app shows its own in-flutter keyboard. + bool _isSystemKeyboardEnabled; bool _isFloatingCursorActive; // The view has reached end of life, and is no longer // allowed to access its textInputDelegate. @@ -579,6 +592,8 @@ - (void)configureWithDictionary:(NSDictionary*)configuration { NSDictionary* autofill = configuration[kAutofillProperties]; self.secureTextEntry = [configuration[kSecureTextEntry] boolValue]; + + _isSystemKeyboardEnabled = shouldShowSystemKeyboard(inputType); self.keyboardType = ToUIKeyboardType(inputType); self.returnKeyType = ToUIReturnKeyType(configuration[kInputAction]); self.autocapitalizationType = ToUITextAutoCapitalizationType(configuration); @@ -625,6 +640,17 @@ - (UITextContentType)textContentType { return _textContentType; } +- (UIInputViewController*)inputViewController { + if (_isSystemKeyboardEnabled) { + return nil; + } + + if (!_inputViewcController) { + _inputViewcController = [UIInputViewController new]; + } + return _inputViewcController; +} + - (id)textInputDelegate { return _decommissioned ? nil : _textInputDelegate; } @@ -649,6 +675,7 @@ - (void)dealloc { [_selectedTextRange release]; [_tokenizer release]; [_autofillId release]; + [_inputViewcController release]; [super dealloc]; } diff --git a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.m b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.m index d52359ecb387f..def757b915926 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.m +++ b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.m @@ -194,6 +194,20 @@ - (void)testKeyboardType { XCTAssertEqual(inputView.keyboardType, UIKeyboardTypeURL); } +- (void)testSettingKeyboardTypeNoneDisablesSystemKeyboard { + NSDictionary* config = self.mutableTemplateCopy; + [config setValue:@{@"name" : @"TextInputType.none"} forKey:@"inputType"]; + [self setClientId:123 configuration:config]; + + // Verify the view's inputViewController is not nil; + XCTAssertNotNil(textInputPlugin.activeView.inputViewController); + + [config setValue:@{@"name" : @"TextInputType.url"} forKey:@"inputType"]; + [self setClientId:124 configuration:config]; + XCTAssertNotNil(textInputPlugin.activeView); + XCTAssertNil(textInputPlugin.activeView.inputViewController); +} + - (void)testAutocorrectionPromptRectAppears { FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithFrame:CGRectZero]; inputView.textInputDelegate = engine; From c24490bee980ec8a1d242bd694ab54165845ae35 Mon Sep 17 00:00:00 2001 From: LongCat is Looong <31859944+LongCatIsLooong@users.noreply.github.com> Date: Sat, 26 Jun 2021 09:43:43 -0700 Subject: [PATCH 2/2] fix typo --- .../ios/framework/Source/FlutterTextInputPlugin.mm | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm index 9f641acf02017..b8f9cfd803006 100644 --- a/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm +++ b/shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm @@ -524,7 +524,7 @@ @implementation FlutterTextInputView { int _textInputClient; const char* _selectionAffinity; FlutterTextRange* _selectedTextRange; - UIInputViewController* _inputViewcController; + UIInputViewController* _inputViewController; CGRect _cachedFirstRect; // Whether to show the system keyboard when this view // becomes the first responder. Typically set to false @@ -645,10 +645,10 @@ - (UIInputViewController*)inputViewController { return nil; } - if (!_inputViewcController) { - _inputViewcController = [UIInputViewController new]; + if (!_inputViewController) { + _inputViewController = [UIInputViewController new]; } - return _inputViewcController; + return _inputViewController; } - (id)textInputDelegate { @@ -675,7 +675,7 @@ - (void)dealloc { [_selectedTextRange release]; [_tokenizer release]; [_autofillId release]; - [_inputViewcController release]; + [_inputViewController release]; [super dealloc]; }