-
Notifications
You must be signed in to change notification settings - Fork 24.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix Multiline TextInput with a fixed height scrolls to the bottom when prepending new lines to the text #38679
Changes from 10 commits
8658471
3ac73aa
64b64e4
323cd2d
ce0c4d8
56a2859
39d0351
0a29729
d996eef
abbd60e
00bcc51
3318f3e
61dd72d
44207f0
2e13d47
e3dfac0
22b7747
65e9946
6340d60
a44d620
358706c
38a7bf0
b2580e3
55d11bf
48b2207
aff06a4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -594,6 +594,22 @@ - (void)_setAttributedString:(NSAttributedString *)attributedString | |
} | ||
UITextRange *selectedRange = _backedTextInputView.selectedTextRange; | ||
NSInteger oldTextLength = _backedTextInputView.attributedText.string.length; | ||
BOOL previousScrollEnabled = _backedTextInputView.scrollEnabled; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From sammy-SC
|
||
NSInteger previousOffsetStart = [_backedTextInputView offsetFromPosition:_backedTextInputView.beginningOfDocument | ||
toPosition:selectedRange.start]; | ||
if (previousScrollEnabled && previousOffsetStart > 0 && attributedString.string.length >= previousOffsetStart) { | ||
NSString *lastChar = [attributedString.string substringWithRange:NSMakeRange(previousOffsetStart - 1, 1)]; | ||
NSInteger previousOffsetFromEnd = oldTextLength - previousOffsetStart; | ||
if (previousOffsetFromEnd > 0 && [lastChar isEqual:@"\n"]) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From sammy-SC
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is jogging some memories of what I was confused about back in August, and needed to refresh on again 😅. Could be good to keep an explanation of how newline specifically effects paragraph composition, which is why it is being special cased. Like, the comment from Sam, about keeping some of the less intuitive details, in code, instead of in review. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @NickGerleman #38679 (comment)
I updated the PR to handle any change in the AttributedString (for example color, adding or deleting a paragraph, changing the lineHeight). Expensify/App#19507 (comment)
FIRST EXAMPLE: Adding a new paragraph with the new line character SECOND EXAMPLE: Modifying Text styles lineHeight or color causes mutation of the UITextView AttributedText and moves the cursor to the end of the text (Expensify/App#19507 (comment)).
UIKit issue https://developer.apple.com/forums/thread/652653. |
||
_backedTextInputView.scrollEnabled = NO; | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could you explain this heuristic? Is it specific to adding newlines? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks @NickGerleman
Scrolling is temporarily disabled when prepending a new line character to the attributed string:
Yes. It is specific to adding new lines. It is iOS issue 652653, previously addressed with commit Maintain cursor position when the text changes in the text input.
https://developer.apple.com/forums/thread/652653 Reproducing the issue on an iOS App without react-native
2023-06-17.18-16-16.mp4Sourcecode available at Expensify/App#19507 (comment). Details of the changes in the AttributedString attributes (paragraph alignment) when adding new lineBefore one of the AttributedString spans has NSParagraphStyle Alignment 0. The string text is CLICK TO OPEN ATTRIBUTED STRING DETAILS
After The AttributedString has only one span. The span has NSParagraphStyle Alignment 4. The string text is CLICK TO OPEN ATTRIBUTED STRING DETAILS
I included a video of the two examples at this link. |
||
|
||
_backedTextInputView.attributedText = attributedString; | ||
if (!_backedTextInputView.scrollEnabled && previousScrollEnabled) { | ||
_backedTextInputView.scrollEnabled = YES; | ||
} | ||
|
||
_backedTextInputView.attributedText = attributedString; | ||
if (selectedRange.empty) { | ||
// Maintaining a cursor position relative to the end of the old text. | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From sammy-SC:
Context for the last one, we've been trying to more often leverage Meta's existing UI testing infra, against examples in RNTester, when we are making adjacent changes.
There isn't currently an equivalent in OSS, so I will be writing some tests, that look like:
If we wanted to consider a matrix of different scroll offsets, characters, cursor positions, etc, what would the full test matrix look like?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@NickGerleman #38679 (comment)
Yes. It is a UIKit problem (Expensify/App#19507 (comment), Expensify/App#19507 (comment) and https://developer.apple.com/forums/thread/652653).
I prepared the following test cases:
Sourcecode of the Example