diff --git a/CHANGELOG.md b/CHANGELOG.md index 629b9c1c44..0ecb119f48 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -55,6 +55,7 @@ - [ASCollectionView] Fix a crash that is caused by clearing a collection view's data while it's still being used. [Huy Nguyen](https://github.com/nguyenhuy) [#1154](https://github.com/TextureGroup/Texture/pull/1154) - Clean up timing of layout tree flattening/ copying of unflattened tree for Weaver. [Michael Zuccarino](https://github.com/mikezucc) [#1157](https://github.com/TextureGroup/Texture/pull/1157) - Fix crash setting attributed text on multiple threads [Michael Schneider](https://github.com/maicki) +- [ASTextNode2] Ignore certain text alignments while calculating intrinsic size [Huy Nguyen](https://github.com/nguyenhuy) [#1166](https://github.com/TextureGroup/Texture/pull/1166) ## 2.7 - Fix pager node for interface coalescing. [Max Wang](https://github.com/wsdwsd0829) [#877](https://github.com/TextureGroup/Texture/pull/877) diff --git a/Source/ASTextNode2.mm b/Source/ASTextNode2.mm index 1cd9444c4e..194921bbe7 100644 --- a/Source/ASTextNode2.mm +++ b/Source/ASTextNode2.mm @@ -234,9 +234,17 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; _textContainer.size = constrainedSize; [self _ensureTruncationText]; - + + // If the constrained size has a max/inf value on the text's forward direction, the text node is calculating its intrinsic size. + BOOL isCalculatingIntrinsicSize; + if (_textContainer.isVerticalForm) { + isCalculatingIntrinsicSize = (_textContainer.size.height >= ASTextContainerMaxSize.height); + } else { + isCalculatingIntrinsicSize = (_textContainer.size.width >= ASTextContainerMaxSize.width); + } + NSMutableAttributedString *mutableText = [_attributedText mutableCopy]; - [self prepareAttributedString:mutableText]; + [self prepareAttributedString:mutableText isForIntrinsicSize:isCalculatingIntrinsicSize]; ASTextLayout *layout = [ASTextNode2 compatibleLayoutWithContainer:_textContainer text:mutableText]; return layout.textBoundingSize; @@ -321,18 +329,31 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; return _textContainer.exclusionPaths; } -- (void)prepareAttributedString:(NSMutableAttributedString *)attributedString +- (void)prepareAttributedString:(NSMutableAttributedString *)attributedString isForIntrinsicSize:(BOOL)isForIntrinsicSize { ASLockScopeSelf(); - - // Apply paragraph style if needed + + // Apply/Fix paragraph style if needed [attributedString enumerateAttribute:NSParagraphStyleAttributeName inRange:NSMakeRange(0, attributedString.length) options:kNilOptions usingBlock:^(NSParagraphStyle *style, NSRange range, BOOL * _Nonnull stop) { - if (style == nil || style.lineBreakMode == _truncationMode) { + + const BOOL applyTruncationMode = (style != nil && style.lineBreakMode != _truncationMode); + // Only "left" and "justified" alignments are supported while calculating intrinsic size. + // Other alignments like "right", "center" and "natural" cause the size to be bigger than needed and thus should be ignored/overridden. + const BOOL forceLeftAlignment = (style != nil + && isForIntrinsicSize + && style.alignment != NSTextAlignmentLeft + && style.alignment != NSTextAlignmentJustified); + if (!applyTruncationMode && !forceLeftAlignment) { return; } - - NSMutableParagraphStyle *paragraphStyle = [style mutableCopy] ?: [[NSMutableParagraphStyle alloc] init]; - paragraphStyle.lineBreakMode = _truncationMode; + + NSMutableParagraphStyle *paragraphStyle = [style mutableCopy]; + if (applyTruncationMode) { + paragraphStyle.lineBreakMode = _truncationMode; + } + if (forceLeftAlignment) { + paragraphStyle.alignment = NSTextAlignmentLeft; + } [attributedString addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:range]; }]; @@ -364,8 +385,8 @@ static NSArray *DefaultLinkAttributeNames = @[ NSLinkAttributeName ]; copiedContainer.size = self.bounds.size; [copiedContainer makeImmutable]; NSMutableAttributedString *mutableText = [_attributedText mutableCopy] ?: [[NSMutableAttributedString alloc] init]; - - [self prepareAttributedString:mutableText]; + + [self prepareAttributedString:mutableText isForIntrinsicSize:NO]; return @{ @"container": copiedContainer,