From 4118aefdbb81fb0d5e078998d5a97b8fe376946a Mon Sep 17 00:00:00 2001 From: delekta Date: Wed, 11 Feb 2026 16:03:48 +0100 Subject: [PATCH] Fix: [iOS] Correctly mark inline attachments as clipped when in truncated text range --- .../textlayoutmanager/RCTTextLayoutManager.mm | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm b/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm index 216bb23beb023e..55d41c4d929ea4 100644 --- a/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm +++ b/packages/react-native/ReactCommon/react/renderer/textlayoutmanager/platform/ios/react/renderer/textlayoutmanager/RCTTextLayoutManager.mm @@ -390,6 +390,8 @@ - (TextMeasurement)_measureTextStorage:(NSTextStorage *)textStorage ceil(size.width * layoutContext.pointScaleFactor) / layoutContext.pointScaleFactor, ceil(size.height * layoutContext.pointScaleFactor) / layoutContext.pointScaleFactor}; + NSRange visibleGlyphRange = [layoutManager glyphRangeForTextContainer:textContainer]; + __block auto attachments = TextMeasurement::Attachments{}; [textStorage @@ -405,7 +407,14 @@ - (TextMeasurement)_measureTextStorage:(NSTextStorage *)textStorage actualCharacterRange:NULL]; NSRange truncatedRange = [layoutManager truncatedGlyphRangeInLineFragmentForGlyphAtIndex:attachmentGlyphRange.location]; - if (truncatedRange.location != NSNotFound && attachmentGlyphRange.location >= truncatedRange.location) { + + // Attachment on a line that did not fit (e.g. on the 4th line when the container is limited to 3 lines) + BOOL isOutsideVisibleRange = !NSLocationInRange(attachmentGlyphRange.location, visibleGlyphRange); + // Attachment in the ellipsis range of the last visible line (line truncated with "..." and the attachment falls in that portion) + BOOL isInTruncatedRange = truncatedRange.location != NSNotFound && + attachmentGlyphRange.location >= truncatedRange.location; + + if (isOutsideVisibleRange || isInTruncatedRange) { attachments.push_back(TextMeasurement::Attachment{.isClipped = true}); } else { CGSize attachmentSize = attachment.bounds.size;