mirror of
https://github.com/facebook/react-native.git
synced 2024-11-21 20:50:09 +00:00
TextLayout: take full width if text wrapped (#47435)
Summary: ### Problem The calculated width for a multiline text is based on the longest line. However it does not account for text that wraps. **Example** if numberOfLines=1 and the text wraps ``` +---------------------------+ This is a long text that will wrap +---------------------------+ ``` The TextView will render ``` +---------------------------+ This is a long text t... +---------------------------+ ``` because the `calculatedWidth` took the width of the first line. Also see https://github.com/facebook/react-native/pull/41770#issuecomment-2453611554 for additional context. ### Solution If the text wraps, take the whole width. ``` +---------------------------+ This is a long text that w... +---------------------------+ ``` Fixes https://github.com/facebook/react-native/issues/39722 Fixes https://github.com/facebook/yoga/issues/1730 ## Changelog: [GENERAL] [FIXED] - Fix text not taking full width Pull Request resolved: https://github.com/facebook/react-native/pull/47435 Test Plan: ```tsx <Text numberOfLines={1} style={{ backgroundColor: 'red', alignSelf: 'flex-start', color: 'white', fontSize: 34, }}> {'This is a long text that will wrap.'} </Text> <Text numberOfLines={3} style={{ backgroundColor: 'red', alignSelf: 'flex-start', color: 'white', fontSize: 34, }}> { '1\n\ntest\nThis is a long text that will wrap.This is a long text that will wrap.This is a long text that will wrap.\n' } </Text> <Text numberOfLines={3} style={{ backgroundColor: 'red', alignSelf: 'flex-start', color: 'white', fontSize: 34, }}> { '1\n\nThis is a long text that will wrap.This is a long text that will wrap.This is a long text that will wrap.\n' } </Text> ``` 1. Verify that the first and third text take full width 2. Verify that the second text does not take full width | Before | After | |:------:|:-----:| | <img width="480" alt="Screenshot 2024-11-05 at 9 00 24 PM" src="https://github.com/user-attachments/assets/b8d765c0-f4b1-42c6-afc7-75862c52612a"> | <img width="480" alt="Screenshot 2024-11-05 at 9 01 49 PM" src="https://github.com/user-attachments/assets/f1534c14-a56a-4d44-8edc-4d9f75166cb2"> | Reviewed By: NickGerleman Differential Revision: D65521732 Pulled By: realsoelynn fbshipit-source-id: 0bb0bb306445e73e8b24ff4c02921739d15ee07e
This commit is contained in:
parent
105ad855d9
commit
550b0c0ed1
@ -707,6 +707,10 @@ public class TextLayoutManager {
|
||||
for (int lineIndex = 0; lineIndex < calculatedLineCount; lineIndex++) {
|
||||
boolean endsWithNewLine =
|
||||
text.length() > 0 && text.charAt(layout.getLineEnd(lineIndex) - 1) == '\n';
|
||||
if (!endsWithNewLine && lineIndex + 1 < layout.getLineCount()) {
|
||||
calculatedWidth = width;
|
||||
break;
|
||||
}
|
||||
float lineWidth =
|
||||
endsWithNewLine ? layout.getLineMax(lineIndex) : layout.getLineWidth(lineIndex);
|
||||
if (lineWidth > calculatedWidth) {
|
||||
|
@ -347,8 +347,33 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi
|
||||
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
|
||||
[layoutManager ensureLayoutForTextContainer:textContainer];
|
||||
|
||||
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
|
||||
__block BOOL textDidWrap = NO;
|
||||
[layoutManager
|
||||
enumerateLineFragmentsForGlyphRange:glyphRange
|
||||
usingBlock:^(
|
||||
CGRect overallRect,
|
||||
CGRect usedRect,
|
||||
NSTextContainer *_Nonnull usedTextContainer,
|
||||
NSRange lineGlyphRange,
|
||||
BOOL *_Nonnull stop) {
|
||||
NSRange range = [layoutManager characterRangeForGlyphRange:lineGlyphRange
|
||||
actualGlyphRange:nil];
|
||||
NSUInteger lastCharacterIndex = range.location + range.length - 1;
|
||||
BOOL endsWithNewLine =
|
||||
[textStorage.string characterAtIndex:lastCharacterIndex] == '\n';
|
||||
if (!endsWithNewLine && textStorage.string.length > lastCharacterIndex + 1) {
|
||||
textDidWrap = YES;
|
||||
*stop = YES;
|
||||
}
|
||||
}];
|
||||
|
||||
CGSize size = [layoutManager usedRectForTextContainer:textContainer].size;
|
||||
|
||||
if (textDidWrap) {
|
||||
size.width = textContainer.size.width;
|
||||
}
|
||||
|
||||
size = (CGSize){RCTCeilPixelValue(size.width), RCTCeilPixelValue(size.height)};
|
||||
|
||||
__block auto attachments = TextMeasurement::Attachments{};
|
||||
|
Loading…
Reference in New Issue
Block a user