Skip to content

Commit 3a776a0

Browse files
authored
iOS Text Input Refactoring (#3004)
iOS text input had a single monolithic `UIKitTextInputService` that handled both the Compose path (Compose draws caret/selection) and the NITI path (UIKit owns caret, handles and context menu) with `if (usingNativeTextInput)` branches throughout, and a single shared view reused across sessions. Each text input session now gets its own dedicated connection object that owns its view for the duration of the session. The two paths are split into separate classes with no branching in shared code. Class Hierarchy changes **Before:** ``` UIKitTextInputService └── IntermediateTextInputUIView (IOSSkikoInput protocol) ``` **After:** ``` UIKitTextInputService ├── ComposeTextInputConnection (TextInputConnection) → ComposeTextInputView (TextEditingDelegate) └── NativeTextInputConnection (TextInputConnection) → NativeTextInputView (NativeTextEditingDelegate) ``` `SelectionContainerConnection` extends `ComposeTextInputConnection` and makes the SelectionContainer menu scenario explicit — instead of scattered conditions inside `showMenu`, there is now a dedicated connection type that clearly represents opening a context menu without an active text input session. ### Fixes: [CMP-9972](https://youtrack.jetbrains.com/issue/CMP-9972) [iOS] Refactor iOS Text Input ## Testing This should be tested by QA ## Release Notes N/A
1 parent 9adc301 commit 3a776a0

16 files changed

Lines changed: 2318 additions & 1676 deletions

File tree

compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPEditMenuView.h

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,10 @@
1616

1717
#import <UIKit/UIKit.h>
1818
#import "CMPEditMenuCustomAction.h"
19-
#import "CMPTextInputView.h"
2019

21-
@interface CMPEditMenuView : CMPTextInputView
20+
@interface CMPEditMenuView : UIView
2221

2322
@property (readonly) BOOL isEditMenuShown;
24-
@property (readonly) BOOL shouldUseNonComposeMenuActions;
2523

2624
- (void)showEditMenuAtRect:(CGRect)targetRect
2725
copy:(void (^)(void))copyBlock
@@ -44,8 +42,4 @@
4442

4543
- (UIView *)inputAccessoryView;
4644

47-
- (void)activateTextInputInteractionIfNeeded;
48-
49-
- (void)deactivateTextInputInteractionIfNeeded;
50-
5145
@end

compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPEditMenuView.m

Lines changed: 1 addition & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,6 @@ @interface CMPEditMenuView() <UIEditMenuInteractionDelegate>
7474

7575
@property (assign, nonatomic) CGRect targetRect;
7676
@property (assign, nonatomic) BOOL isEditMenuShown;
77-
@property (assign, nonatomic) BOOL shouldUseNonComposeMenuActions;
7877

7978
@property (readwrite) UIEditMenuInteraction* editInteraction API_AVAILABLE(ios(16.0));
8079

@@ -325,9 +324,7 @@ - (BOOL)canPerformAction:(SEL)action withSender:(id)sender {
325324
if (@selector(customAction8:) == action) return self.customActions.count > 8;
326325
if (@selector(customAction9:) == action) return self.customActions.count > 9;
327326

328-
if (self.shouldUseNonComposeMenuActions) {
329-
return [super canPerformAction:action withSender:sender];
330-
} else { return NO; }
327+
return NO;
331328
}
332329

333330
- (void)copy:(id)sender {
@@ -441,24 +438,4 @@ - (UIMenu *)editMenuInteraction:(UIEditMenuInteraction *)interaction
441438
return [UIMenu menuWithTitle:@"" children:allActions];
442439
}
443440

444-
- (void)activateTextInputInteractionIfNeeded {
445-
if (@available(iOS 17, *)) {
446-
for (id<UIInteraction> interaction in self.interactions) {
447-
if ([interaction isKindOfClass:[UITextSelectionDisplayInteraction class]]) {
448-
[((UITextSelectionDisplayInteraction *)interaction) setActivated:YES];
449-
}
450-
}
451-
}
452-
}
453-
454-
- (void)deactivateTextInputInteractionIfNeeded {
455-
if (@available(iOS 17, *)) {
456-
for (id<UIInteraction> interaction in self.interactions) {
457-
if ([interaction isKindOfClass:[UITextSelectionDisplayInteraction class]]) {
458-
[((UITextSelectionDisplayInteraction *)interaction) setActivated:NO];
459-
}
460-
}
461-
}
462-
}
463-
464441
@end

compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPTextInputView.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,8 @@ NS_ASSUME_NONNULL_BEGIN
2626
atCharacterOffset:(NSInteger)offset CMP_ABSTRACT_FUNCTION;
2727
NS_ASSUME_NONNULL_END
2828

29+
- (void)activateTextInputInteractionIfNeeded;
30+
31+
- (void)deactivateTextInputInteractionIfNeeded;
32+
2933
@end

compose/ui/ui-uikit/src/iosMain/objc/CMPUIKitUtils/CMPUIKitUtils/CMPTextInputView.m

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,4 +125,24 @@ - (void)insertText:(nonnull NSString *)text {
125125
CMP_ABSTRACT_FUNCTION_CALLED
126126
}
127127

128+
- (void)activateTextInputInteractionIfNeeded {
129+
if (@available(iOS 17, *)) {
130+
for (id<UIInteraction> interaction in self.interactions) {
131+
if ([interaction isKindOfClass:[UITextSelectionDisplayInteraction class]]) {
132+
[((UITextSelectionDisplayInteraction *)interaction) setActivated:YES];
133+
}
134+
}
135+
}
136+
}
137+
138+
- (void)deactivateTextInputInteractionIfNeeded {
139+
if (@available(iOS 17, *)) {
140+
for (id<UIInteraction> interaction in self.interactions) {
141+
if ([interaction isKindOfClass:[UITextSelectionDisplayInteraction class]]) {
142+
[((UITextSelectionDisplayInteraction *)interaction) setActivated:NO];
143+
}
144+
}
145+
}
146+
}
147+
128148
@end

compose/ui/ui/src/iosMain/kotlin/androidx/compose/ui/platform/IOSSkikoInput.ios.kt

Lines changed: 0 additions & 198 deletions
This file was deleted.

0 commit comments

Comments
 (0)