Skip to content
This repository was archived by the owner on Feb 25, 2025. It is now read-only.

Commit 42b4cfd

Browse files
authored
[ios][autocorrection]disable auto-correction highlight in iOS 17 (#44176)
This PR disables the "auto-correction highlight" feature in iOS 17. This feature was introduced in flutter/flutter#45354 and #13959 (CC: @LongCatIsLooong who was the original author) I have created [a new issue](flutter/flutter#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 flutter/flutter#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
1 parent 5dd660c commit 42b4cfd

File tree

2 files changed

+33
-10
lines changed

2 files changed

+33
-10
lines changed

shell/platform/darwin/ios/framework/Source/FlutterTextInputPlugin.mm

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1632,10 +1632,21 @@ - (CGRect)firstRectForRange:(UITextRange*)range {
16321632

16331633
if (_scribbleInteractionStatus == FlutterScribbleInteractionStatusNone &&
16341634
_scribbleFocusStatus == FlutterScribbleFocusStatusUnfocused) {
1635-
[self.textInputDelegate flutterTextInputView:self
1636-
showAutocorrectionPromptRectForStart:start
1637-
end:end
1638-
withClient:_textInputClient];
1635+
if (@available(iOS 17.0, *)) {
1636+
// Disable auto-correction highlight feature for iOS 17+.
1637+
// In iOS 17+, whenever a character is inserted or deleted, the system will always query
1638+
// the rect for every single character of the current word.
1639+
// GitHub Issue: https://github.com/flutter/flutter/issues/128406
1640+
} else {
1641+
// This tells the framework to show the highlight for incorrectly spelled word that is
1642+
// about to be auto-corrected.
1643+
// There is no other UITextInput API that informs about the auto-correction highlight.
1644+
// So we simply add the call here as a workaround.
1645+
[self.textInputDelegate flutterTextInputView:self
1646+
showAutocorrectionPromptRectForStart:start
1647+
end:end
1648+
withClient:_textInputClient];
1649+
}
16391650
}
16401651

16411652
NSUInteger first = start;

shell/platform/darwin/ios/framework/Source/FlutterTextInputPluginTest.mm

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -313,15 +313,22 @@ - (void)testSettingKeyboardTypeNoneDisablesSystemKeyboard {
313313
XCTAssertNil(textInputPlugin.activeView.inputViewController);
314314
}
315315

316-
- (void)testAutocorrectionPromptRectAppears {
316+
- (void)testAutocorrectionPromptRectAppearsBeforeIOS17AndDoesNotAppearAfterIOS17 {
317317
FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
318318
[inputView firstRectForRange:[FlutterTextRange rangeWithNSRange:NSMakeRange(0, 1)]];
319319

320-
// Verify behavior.
321-
OCMVerify([engine flutterTextInputView:inputView
322-
showAutocorrectionPromptRectForStart:0
323-
end:1
324-
withClient:0]);
320+
if (@available(iOS 17.0, *)) {
321+
// Auto-correction prompt is disabled in iOS 17+.
322+
OCMVerify(never(), [engine flutterTextInputView:inputView
323+
showAutocorrectionPromptRectForStart:0
324+
end:1
325+
withClient:0]);
326+
} else {
327+
OCMVerify([engine flutterTextInputView:inputView
328+
showAutocorrectionPromptRectForStart:0
329+
end:1
330+
withClient:0]);
331+
}
325332
}
326333

327334
- (void)testIgnoresSelectionChangeIfSelectionIsDisabled {
@@ -353,6 +360,11 @@ - (void)testIgnoresSelectionChangeIfSelectionIsDisabled {
353360
}
354361

355362
- (void)testAutocorrectionPromptRectDoesNotAppearDuringScribble {
363+
// Auto-correction prompt is disabled in iOS 17+.
364+
if (@available(iOS 17.0, *)) {
365+
return;
366+
}
367+
356368
if (@available(iOS 14.0, *)) {
357369
FlutterTextInputView* inputView = [[FlutterTextInputView alloc] initWithOwner:textInputPlugin];
358370

0 commit comments

Comments
 (0)