[ios][autocorrection]disable auto-correction highlight in iOS 17 (flutter/engine#44176)

This PR disables the "auto-correction highlight" feature in iOS 17. 

This feature was introduced in https://github.com/flutter/flutter/pull/45354 and https://github.com/flutter/engine/pull/13959/ (CC: @LongCatIsLooong who was the original author)

I have created [a new issue](https://github.com/flutter/flutter/issues/131622) to find other approaches to re-enable this feature. 

**Note that "auto-correction" itself still works, it's only the "highlight" part is disabled:**

- iOS 16 with highlight:
https://github.com/flutter/engine/assets/41930132/2fe7bbf6-f2db-4212-a020-e420ad8dd5e6

- iOS 17 without highlight:
https://github.com/flutter/engine/assets/41930132/34f34743-6bef-4e93-80d2-d04c92ba59bf

## Why disable this feature?

The original PR uses `UITextInput::firstRectForRange` API for auto-correction, since Apple does not provide any other API when auto-correction should show up, so the original PR used this API as a workaround. 

In iOS 17, Apple changed a few `UITextInput` behaviors:  
- UIKit does not query `UITextInput::firstRectForRange` for text range of the auto-corrected word any more. 
- But instead, it repeatedly queries every single character of the current word (after entering or deleting a character), regardless whether the word should be auto-corrected or not. 

I have tried all other `UITextInput` APIs that takes a text range, and none are suitable for auto-correction feature. As a result, I have to disable this feature for iOS 17 for now. 

*List which issues are fixed by this PR. You must list at least one issue.*

Fixes https://github.com/flutter/flutter/issues/128406

*If you had to change anything in the [flutter/tests] repo, include a link to the migration guide as per the [breaking change policy].*

[C++, Objective-C, Java style guides]: https://github.com/flutter/engine/blob/main/CONTRIBUTING.md#style
This commit is contained in:
hellohuanlin
2023-08-02 11:20:17 -07:00
committed by GitHub
parent d4d816b177
commit da9b932e28
2 changed files with 33 additions and 10 deletions

View File

@@ -1632,10 +1632,21 @@ static BOOL IsSelectionRectBoundaryCloserToPoint(CGPoint point,
if (_scribbleInteractionStatus == FlutterScribbleInteractionStatusNone &&
_scribbleFocusStatus == FlutterScribbleFocusStatusUnfocused) {
[self.textInputDelegate flutterTextInputView:self
showAutocorrectionPromptRectForStart:start
end:end
withClient:_textInputClient];
if (@available(iOS 17.0, *)) {
// Disable auto-correction highlight feature for iOS 17+.
// In iOS 17+, whenever a character is inserted or deleted, the system will always query
// the rect for every single character of the current word.
// GitHub Issue: https://github.com/flutter/flutter/issues/128406
} else {
// This tells the framework to show the highlight for incorrectly spelled word that is
// about to be auto-corrected.
// There is no other UITextInput API that informs about the auto-correction highlight.
// So we simply add the call here as a workaround.
[self.textInputDelegate flutterTextInputView:self
showAutocorrectionPromptRectForStart:start
end:end
withClient:_textInputClient];
}
}
NSUInteger first = start;

View File

@@ -313,15 +313,22 @@ FLUTTER_ASSERT_ARC
XCTAssertNil(textInputPlugin.activeView.inputViewController);
}
- (void)testAutocorrectionPromptRectAppears {
- (void)testAutocorrectionPromptRectAppearsBeforeIOS17AndDoesNotAppearAfterIOS17 {
FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
[inputView firstRectForRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]];
// Verify behavior.
OCMVerify([engine flutterTextInputView:inputView
showAutocorrectionPromptRectForStart:0
end:1
withClient:0]);
if (@available(iOS 17.0, *)) {
// Auto-correction prompt is disabled in iOS 17+.
OCMVerify(never(), [engine flutterTextInputView:inputView
showAutocorrectionPromptRectForStart:0
end:1
withClient:0]);
} else {
OCMVerify([engine flutterTextInputView:inputView
showAutocorrectionPromptRectForStart:0
end:1
withClient:0]);
}
}
- (void)testIgnoresSelectionChangeIfSelectionIsDisabled {
@@ -353,6 +360,11 @@ FLUTTER_ASSERT_ARC
}
- (void)testAutocorrectionPromptRectDoesNotAppearDuringScribble {
// Auto-correction prompt is disabled in iOS 17+.
if (@available(iOS 17.0, *)) {
return;
}
if (@available(iOS 14.0, *)) {
FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];