Skip to content

Commit b69e281

Browse files
jasozhfacebook-github-bot
authored andcommitted
Draw text with unbounded height on iOS (#59793)
Summary: Fixes an issue where text wrapping behavior on iOS differs from Android and web when the text does not fit in its parent container. ### Root Cause On iOS, React Native lays out text during measurement and drawing. `RCTTextLayoutManager::measureNSAttributedString()` uses an unbounded height during measurement to position where text and inline views should be. However, during drawing, the actual frame size is used. When TextKit reaches a point where the next line of text doesn't fit inside the container's height, it stops wrapping and puts everything on the current line. This leads to different wrapping behavior compared to Android and web, especially when inline views are included in text. ### This PR Modify RCTTextLayoutManager so that drawing also uses unbounded height, matching the existing measurement code. This means TextKit never tries to alter wrapping behavior. Changelog: [iOS][Fixed] - Text taller than a fixed-height `<Text>` now wraps normally and is clipped at the bottom edge, matching Android and web Reviewed By: vzaidman Differential Revision: D127931949
1 parent 93019c4 commit b69e281

1 file changed

Lines changed: 15 additions & 3 deletions

File tree

  • packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager

‎packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm‎

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,18 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi
3939
}
4040
}
4141

42+
// Text is laid out with an unbounded height, as during measurement, so that lines and attachments end up where
43+
// measurement placed them. A container clamped to the frame height makes TextKit squeeze the remaining content into
44+
// the last line that fits. The paragraph view clips the drawing to its bounds.
45+
static CGSize RCTTextLayoutSizeForFrameSize(CGSize frameSize, const ParagraphAttributes &paragraphAttributes)
46+
{
47+
if (paragraphAttributes.adjustsFontSizeToFit) {
48+
// Font scaling shrinks the text until it fits the frame height.
49+
return frameSize;
50+
}
51+
return CGSize{frameSize.width, CGFLOAT_MAX};
52+
}
53+
4254
- (TextMeasurement)measureNSAttributedString:(NSAttributedString *)attributedString
4355
paragraphAttributes:(ParagraphAttributes)paragraphAttributes
4456
layoutContext:(TextLayoutContext)layoutContext
@@ -136,7 +148,7 @@ - (void)drawAttributedString:(const AttributedString &)attributedString
136148
NSTextStorage *textStorage = [self
137149
_textStorageAndLayoutManagerWithAttributesString:[self _nsAttributedStringFromAttributedString:attributedString]
138150
paragraphAttributes:paragraphAttributes
139-
size:frame.size];
151+
size:RCTTextLayoutSizeForFrameSize(frame.size, paragraphAttributes)];
140152
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
141153
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
142154

@@ -475,7 +487,7 @@ - (NSTextStorage *)_textStorageAndLayoutManagerWithAttributesString:(NSAttribute
475487
NSTextStorage *textStorage = [self
476488
_textStorageAndLayoutManagerWithAttributesString:[self _nsAttributedStringFromAttributedString:attributedString]
477489
paragraphAttributes:paragraphAttributes
478-
size:frame.size];
490+
size:RCTTextLayoutSizeForFrameSize(frame.size, paragraphAttributes)];
479491
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
480492
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;
481493

@@ -506,7 +518,7 @@ - (void)getRectWithAttributedString:(const AttributedString &)attributedString
506518
NSTextStorage *textStorage = [self
507519
_textStorageAndLayoutManagerWithAttributesString:[self _nsAttributedStringFromAttributedString:attributedString]
508520
paragraphAttributes:paragraphAttributes
509-
size:frame.size];
521+
size:RCTTextLayoutSizeForFrameSize(frame.size, paragraphAttributes)];
510522

511523
NSLayoutManager *layoutManager = textStorage.layoutManagers.firstObject;
512524
NSTextContainer *textContainer = layoutManager.textContainers.firstObject;

0 commit comments

Comments
 (0)