mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Reland: [iOS] Fixes ellipsis carries background from trimmed text (#45412)
Summary: Reland https://github.com/facebook/react-native/issues/39408 . Try to fix the crash https://github.com/facebook/react-native/issues/37926#issuecomment-2225113557. cc. javache I changed the range from glyph to character because all attributes related APIs are character range. ## Changelog: [IOS] [FIXED] - Fixes ellipsis carries background from trimmed text Pull Request resolved: https://github.com/facebook/react-native/pull/45412 Test Plan: https://github.com/facebook/react-native/issues/37926 . Reviewed By: cipolleschi Differential Revision: D59681679 Pulled By: javache fbshipit-source-id: de4cb73e0304b8c0b0a40f4f6838b2c679747009
This commit is contained in:
committed by
Facebook GitHub Bot
parent
24997dc5ae
commit
9e2f8859c4
@@ -237,6 +237,8 @@
|
||||
maximumFontSize:self.textAttributes.effectiveFont.pointSize];
|
||||
}
|
||||
|
||||
[self processTruncatedAttributedText:textStorage textContainer:textContainer layoutManager:layoutManager];
|
||||
|
||||
if (!exclusiveOwnership) {
|
||||
[_cachedTextStorages setObject:textStorage forKey:key];
|
||||
}
|
||||
@@ -244,6 +246,50 @@
|
||||
return textStorage;
|
||||
}
|
||||
|
||||
- (void)processTruncatedAttributedText:(NSTextStorage *)textStorage
|
||||
textContainer:(NSTextContainer *)textContainer
|
||||
layoutManager:(NSLayoutManager *)layoutManager
|
||||
{
|
||||
if (_maximumNumberOfLines > 0) {
|
||||
[layoutManager ensureLayoutForTextContainer:textContainer];
|
||||
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
|
||||
__block int line = 0;
|
||||
[layoutManager
|
||||
enumerateLineFragmentsForGlyphRange:glyphRange
|
||||
usingBlock:^(
|
||||
CGRect rect,
|
||||
CGRect usedRect,
|
||||
NSTextContainer *_Nonnull _,
|
||||
NSRange lineGlyphRange,
|
||||
BOOL *_Nonnull stop) {
|
||||
if (line == textContainer.maximumNumberOfLines - 1) {
|
||||
NSRange truncatedRange = [layoutManager
|
||||
truncatedGlyphRangeInLineFragmentForGlyphAtIndex:lineGlyphRange.location];
|
||||
|
||||
if (truncatedRange.location != NSNotFound) {
|
||||
NSRange characterRange =
|
||||
[layoutManager characterRangeForGlyphRange:truncatedRange
|
||||
actualGlyphRange:nil];
|
||||
if (characterRange.location > 0 && characterRange.length > 0) {
|
||||
// Remove color attributes for truncated range
|
||||
for (NSAttributedStringKey key in
|
||||
@[ NSForegroundColorAttributeName, NSBackgroundColorAttributeName ]) {
|
||||
[textStorage removeAttribute:key range:characterRange];
|
||||
id attribute = [textStorage attribute:key
|
||||
atIndex:characterRange.location - 1
|
||||
effectiveRange:nil];
|
||||
if (attribute) {
|
||||
[textStorage addAttribute:key value:attribute range:characterRange];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
line++;
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)layoutWithMetrics:(RCTLayoutMetrics)layoutMetrics layoutContext:(RCTLayoutContext)layoutContext
|
||||
{
|
||||
// If the view got new `contentFrame`, we have to redraw it because
|
||||
|
||||
+46
@@ -83,6 +83,9 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi
|
||||
#endif
|
||||
|
||||
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
|
||||
|
||||
[self processTruncatedAttributedText:textStorage textContainer:textContainer layoutManager:layoutManager];
|
||||
|
||||
[layoutManager drawBackgroundForGlyphRange:glyphRange atPoint:frame.origin];
|
||||
[layoutManager drawGlyphsForGlyphRange:glyphRange atPoint:frame.origin];
|
||||
|
||||
@@ -123,6 +126,49 @@ static NSLineBreakMode RCTNSLineBreakModeFromEllipsizeMode(EllipsizeMode ellipsi
|
||||
}
|
||||
}
|
||||
|
||||
- (void)processTruncatedAttributedText:(NSTextStorage *)textStorage
|
||||
textContainer:(NSTextContainer *)textContainer
|
||||
layoutManager:(NSLayoutManager *)layoutManager
|
||||
{
|
||||
if (textContainer.maximumNumberOfLines > 0) {
|
||||
[layoutManager ensureLayoutForTextContainer:textContainer];
|
||||
NSRange glyphRange = [layoutManager glyphRangeForTextContainer:textContainer];
|
||||
__block int line = 0;
|
||||
[layoutManager
|
||||
enumerateLineFragmentsForGlyphRange:glyphRange
|
||||
usingBlock:^(
|
||||
CGRect rect,
|
||||
CGRect usedRect,
|
||||
NSTextContainer *_Nonnull _,
|
||||
NSRange lineGlyphRange,
|
||||
BOOL *_Nonnull stop) {
|
||||
if (line == textContainer.maximumNumberOfLines - 1) {
|
||||
NSRange truncatedRange = [layoutManager
|
||||
truncatedGlyphRangeInLineFragmentForGlyphAtIndex:lineGlyphRange.location];
|
||||
if (truncatedRange.location != NSNotFound) {
|
||||
NSRange characterRange =
|
||||
[layoutManager characterRangeForGlyphRange:truncatedRange
|
||||
actualGlyphRange:nil];
|
||||
if (characterRange.location > 0 && characterRange.length > 0) {
|
||||
// Remove color attributes for truncated range
|
||||
for (NSAttributedStringKey key in
|
||||
@[ NSForegroundColorAttributeName, NSBackgroundColorAttributeName ]) {
|
||||
[textStorage removeAttribute:key range:characterRange];
|
||||
id attribute = [textStorage attribute:key
|
||||
atIndex:characterRange.location - 1
|
||||
effectiveRange:nil];
|
||||
if (attribute) {
|
||||
[textStorage addAttribute:key value:attribute range:characterRange];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
line++;
|
||||
}];
|
||||
}
|
||||
}
|
||||
|
||||
- (LinesMeasurements)getLinesForAttributedString:(facebook::react::AttributedString)attributedString
|
||||
paragraphAttributes:(facebook::react::ParagraphAttributes)paragraphAttributes
|
||||
size:(CGSize)size
|
||||
|
||||
Reference in New Issue
Block a user