Skip to content

Commit 08eed0e

Browse files
hejsztynxCopilot
andauthored
fix(ios): typing attributes clearing on keystrokes (#773)
# Summary There was a bug when in some cases, between selection change and a keystroke, the typing attributes would get cleared, resulting in unstyled text. More info in the `Screenshots / Videos` section. All iOS e2e tests pass. ## Test Plan Reproduce the flow from the attached videos, it should be fine now. ## Screenshots / Videos Before: When changing the selection programmatically, via arrow keys, the typing attributes are correctly preserved https://github.com/user-attachments/assets/12cba319-1dd9-4cf0-8d05-8aa5b96228a7 When using screen taps though, the typing attributes are not preserved resulting in the unstyled text, even though (in this case bold) was marked as active https://github.com/user-attachments/assets/3cbb75e0-0f0d-4c85-82bc-94424899979f After: Typing attributes are correctly preserved whatever the selection change method https://github.com/user-attachments/assets/7f18e399-10ac-4910-9b50-ab2f70f2e912 ## Compatibility | OS | Implemented | | ------- | :---------: | | iOS | ✅ | | Android | ❌ | | Web | ❌ | ## Checklist - [ ] E2E tests are passing - [ ] Required E2E tests have been added (if applicable) --------- Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
1 parent bbe2db4 commit 08eed0e

6 files changed

Lines changed: 50 additions & 0 deletions

File tree

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
appId: swmansion.enriched.example
2+
---
3+
# Verifies that typing attributes are properly preserved on selection changes
4+
- launchApp
5+
6+
- tapOn:
7+
id: 'toggle-screen-button'
8+
9+
- tapOn:
10+
id: "editor-input"
11+
12+
- tapOn:
13+
id: "toolbar-bold"
14+
15+
- inputText: 'bold text'
16+
- pressKey: Enter
17+
- pressKey: Enter
18+
- pressKey: Enter
19+
- inputText: 'another line'
20+
21+
- doubleTapOn:
22+
id: 'editor-input'
23+
point: '20%, 75%'
24+
25+
- tapOn:
26+
id: 'editor-input'
27+
point: '50%, 15%'
28+
29+
- inputText: 'new'
30+
31+
- runFlow:
32+
file: '../subflows/capture_or_assert_screenshot.yaml'
33+
env:
34+
SCREENSHOT_NAME: 'preserve_typing_attributes_on_selection_changes'
9.81 KB
Loading
11.6 KB
Loading

ios/EnrichedTextInputView.mm

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2000,6 +2000,14 @@ - (bool)textView:(UITextView *)textView
20002000
return NO;
20012001
}
20022002

2003+
// To be sure, we re-run typingAttributes management right before the
2004+
// character actually lands. Sometimes, between a selection change and the
2005+
// next keystroke, typing attributes might get removed - this seems like a
2006+
// native TextKit issue.
2007+
if (textView.markedTextRange == nil && text.length > 0) {
2008+
[attributesManager repeatRecentTypingAttributesManagement];
2009+
}
2010+
20032011
return YES;
20042012
}
20052013

ios/inputAttributesManager/InputAttributesManager.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
- (void)didRemoveTypingAttribute:(NSString *)key;
1414
- (void)clearRemovedTypingAttributes;
1515
- (void)manageTypingAttributesWithOnlySelection:(BOOL)onlySelectionChanged;
16+
- (void)repeatRecentTypingAttributesManagement;
1617
- (void)handleDirtyRangesStyling;
1718
- (NSSet<NSString *> *)customAttributesKeys;
1819
@end

ios/inputAttributesManager/InputAttributesManager.mm

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ @implementation InputAttributesManager {
1111
NSMutableArray<NSValue *> *_dirtyRanges;
1212
NSSet *_customAttributesKeys;
1313
NSMutableSet *_removedTypingAttributes;
14+
BOOL _recentOnlySelectionStatus;
1415
}
1516

1617
- (instancetype)initWithInput:(EnrichedTextInputView *)input {
1718
self = [super init];
1819
_input = input;
1920
_dirtyRanges = [[NSMutableArray alloc] init];
2021
_removedTypingAttributes = [[NSMutableSet alloc] init];
22+
_recentOnlySelectionStatus = NO;
2123

2224
// setup customAttributes
2325
NSMutableSet *_customAttrsSet = [[NSMutableSet alloc] init];
@@ -129,6 +131,7 @@ - (void)handleDirtyRangesStyling {
129131
}
130132

131133
- (void)manageTypingAttributesWithOnlySelection:(BOOL)onlySelectionChanged {
134+
_recentOnlySelectionStatus = onlySelectionChanged;
132135
EnrichedInputTextView *textView = _input->textView;
133136
NSRange selectedRange = textView.selectedRange;
134137

@@ -219,4 +222,8 @@ - (void)manageTypingAttributesWithOnlySelection:(BOOL)onlySelectionChanged {
219222
textView.typingAttributes = newAttrs;
220223
}
221224

225+
- (void)repeatRecentTypingAttributesManagement {
226+
[self manageTypingAttributesWithOnlySelection:_recentOnlySelectionStatus];
227+
}
228+
222229
@end

0 commit comments

Comments
 (0)