diff --git a/AsyncDisplayKit.xcodeproj/project.pbxproj b/AsyncDisplayKit.xcodeproj/project.pbxproj index 7cff23c102..29c10b3ca5 100644 --- a/AsyncDisplayKit.xcodeproj/project.pbxproj +++ b/AsyncDisplayKit.xcodeproj/project.pbxproj @@ -217,6 +217,10 @@ 509E68651B3AEDC5009B9150 /* CGRect+ASConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = 205F0E1F1B376416007741D0 /* CGRect+ASConvenience.h */; }; 509E68661B3AEDD7009B9150 /* CGRect+ASConvenience.m in Sources */ = {isa = PBXBuildFile; fileRef = 205F0E201B376416007741D0 /* CGRect+ASConvenience.m */; }; 6BDC61F61979037800E50D21 /* AsyncDisplayKit.h in Headers */ = {isa = PBXBuildFile; fileRef = 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9C3061061B857EC400D0530B /* ASStackTextLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C3061041B857EC400D0530B /* ASStackTextLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9C3061071B857EC400D0530B /* ASStackTextLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C3061041B857EC400D0530B /* ASStackTextLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 9C3061081B857EC400D0530B /* ASStackTextLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C3061051B857EC400D0530B /* ASStackTextLayoutSpec.mm */; }; + 9C3061091B857EC400D0530B /* ASStackTextLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C3061051B857EC400D0530B /* ASStackTextLayoutSpec.mm */; }; 9C49C36F1B853957000B0DD5 /* ASStackLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9C49C3701B853961000B0DD5 /* ASStackLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; }; 9F06E5CD1B4CAF4200F015D8 /* ASCollectionViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */; }; @@ -447,7 +451,7 @@ 058D09D5195D050800B7D73C /* ASControlNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASControlNode.h; sourceTree = ""; }; 058D09D6195D050800B7D73C /* ASControlNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASControlNode.m; sourceTree = ""; }; 058D09D7195D050800B7D73C /* ASControlNode+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASControlNode+Subclasses.h"; sourceTree = ""; }; - 058D09D8195D050800B7D73C /* ASDisplayNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ASDisplayNode.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; + 058D09D8195D050800B7D73C /* ASDisplayNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ASDisplayNode.h; sourceTree = ""; }; 058D09D9195D050800B7D73C /* ASDisplayNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDisplayNode.mm; sourceTree = ""; }; 058D09DA195D050800B7D73C /* ASDisplayNode+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "ASDisplayNode+Subclasses.h"; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; }; 058D09DB195D050800B7D73C /* ASDisplayNodeExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeExtras.h; sourceTree = ""; }; @@ -558,6 +562,8 @@ 4640521E1A3F83C40061C0BA /* ASMultidimensionalArrayUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMultidimensionalArrayUtils.h; sourceTree = ""; }; 4640521F1A3F83C40061C0BA /* ASMultidimensionalArrayUtils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMultidimensionalArrayUtils.mm; sourceTree = ""; }; 6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AsyncDisplayKit.h; sourceTree = ""; }; + 9C3061041B857EC400D0530B /* ASStackTextLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackTextLayoutSpec.h; path = AsyncDisplayKit/Layout/ASStackTextLayoutSpec.h; sourceTree = ""; }; + 9C3061051B857EC400D0530B /* ASStackTextLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASStackTextLayoutSpec.mm; path = AsyncDisplayKit/Layout/ASStackTextLayoutSpec.mm; sourceTree = ""; }; 9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutable.h; path = AsyncDisplayKit/Layout/ASStackLayoutable.h; sourceTree = ""; }; 9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewTests.m; sourceTree = ""; }; AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutDefines.h; path = AsyncDisplayKit/Layout/ASStackLayoutDefines.h; sourceTree = ""; }; @@ -967,6 +973,8 @@ ACF6ED171B17843500DA7C62 /* ASStackLayoutSpec.mm */, ACF6ED181B17843500DA7C62 /* ASStaticLayoutSpec.h */, ACF6ED191B17843500DA7C62 /* ASStaticLayoutSpec.mm */, + 9C3061041B857EC400D0530B /* ASStackTextLayoutSpec.h */, + 9C3061051B857EC400D0530B /* ASStackTextLayoutSpec.mm */, ); name = Layout; path = ..; @@ -1074,6 +1082,7 @@ 058D0A67195D05DC00B7D73C /* NSMutableAttributedString+TextKitAdditions.m in Headers */, 058D0A68195D05EC00B7D73C /* _ASAsyncTransaction.h in Headers */, 205F0E0F1B371875007741D0 /* UICollectionViewLayout+ASConvenience.h in Headers */, + 9C3061061B857EC400D0530B /* ASStackTextLayoutSpec.h in Headers */, 058D0A69195D05EC00B7D73C /* _ASAsyncTransaction.m in Headers */, 058D0A6A195D05EC00B7D73C /* _ASAsyncTransactionContainer+Private.h in Headers */, 058D0A6B195D05EC00B7D73C /* _ASAsyncTransactionContainer.h in Headers */, @@ -1148,6 +1157,7 @@ B35061F31B010EFD0018CF92 /* ASCellNode.h in Headers */, 34EFC76C1B701CED00AD841F /* ASOverlayLayoutSpec.h in Headers */, B35062201B010EFD0018CF92 /* ASLayoutController.h in Headers */, + 9C3061071B857EC400D0530B /* ASStackTextLayoutSpec.h in Headers */, B35062571B010F070018CF92 /* ASAssert.h in Headers */, B35062411B010EFD0018CF92 /* _ASAsyncTransactionGroup.h in Headers */, B350623C1B010EFD0018CF92 /* _ASAsyncTransaction.h in Headers */, @@ -1451,6 +1461,7 @@ 0549634A1A1EA066000F8E56 /* ASBasicImageDownloader.mm in Sources */, 058D0A14195D050800B7D73C /* ASDisplayNode.mm in Sources */, 058D0A1B195D050800B7D73C /* ASMutableAttributedStringBuilder.m in Sources */, + 9C3061081B857EC400D0530B /* ASStackTextLayoutSpec.mm in Sources */, 058D0A2B195D050800B7D73C /* ASImageNode+CGExtras.m in Sources */, 058D0A24195D050800B7D73C /* _ASAsyncTransactionGroup.m in Sources */, 058D0A1C195D050800B7D73C /* ASTextNodeCoreTextAdditions.m in Sources */, @@ -1512,6 +1523,7 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 9C3061091B857EC400D0530B /* ASStackTextLayoutSpec.mm in Sources */, 34EFC7641B701CC600AD841F /* ASCenterLayoutSpec.mm in Sources */, B350623B1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.m in Sources */, B35062401B010EFD0018CF92 /* _ASAsyncTransactionContainer.m in Sources */, diff --git a/AsyncDisplayKit/ASTextNode.h b/AsyncDisplayKit/ASTextNode.h index fc520c1232..681c2cb71e 100644 --- a/AsyncDisplayKit/ASTextNode.h +++ b/AsyncDisplayKit/ASTextNode.h @@ -30,7 +30,7 @@ typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) { @abstract Draws interactive rich text. @discussion Backed by TextKit. */ -@interface ASTextNode : ASControlNode +@interface ASTextNode : ASControlNode /** @abstract The attributed string to show. diff --git a/AsyncDisplayKit/ASTextNode.mm b/AsyncDisplayKit/ASTextNode.mm index 8107fc6ece..7ca68f5177 100644 --- a/AsyncDisplayKit/ASTextNode.mm +++ b/AsyncDisplayKit/ASTextNode.mm @@ -106,11 +106,11 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f) ASTextNodeShadower *_shadower; UILongPressGestureRecognizer *_longPressGestureRecognizer; - - CGFloat _topBaseline; - CGFloat _bottomBaseline; } +@synthesize ascender = _ascender; +@synthesize descender = _descender; + #pragma mark - NSObject - (instancetype)init @@ -360,24 +360,8 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f) } }); - _topBaseline = round([[attributedString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL] ascender] * ASScreenScale())/ASScreenScale(); - _bottomBaseline = round([[attributedString attribute:NSFontAttributeName atIndex:attributedString.length - 1 effectiveRange:NULL] descender] * ASScreenScale())/ASScreenScale(); -} - -#pragma mark - Baseline computation - -- (CGFloat)distanceToBaseline:(ASStackLayoutAlignItems)baselineAlignmentType -{ - switch (baselineAlignmentType) { - case ASStackLayoutAlignItemsLastBaseline: - return self.calculatedSize.height + _bottomBaseline; - - case ASStackLayoutAlignItemsFirstBaseline: - return _topBaseline; - - default: - return 0; - } + _ascender = round([[attributedString attribute:NSFontAttributeName atIndex:0 effectiveRange:NULL] ascender] * ASScreenScale())/ASScreenScale(); + _descender = round([[attributedString attribute:NSFontAttributeName atIndex:attributedString.length - 1 effectiveRange:NULL] descender] * ASScreenScale())/ASScreenScale(); } #pragma mark - Text Layout diff --git a/AsyncDisplayKit/Layout/ASLayoutSpec.mm b/AsyncDisplayKit/Layout/ASLayoutSpec.mm index 34f6206e1b..8b3efd6f4d 100644 --- a/AsyncDisplayKit/Layout/ASLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASLayoutSpec.mm @@ -34,11 +34,6 @@ return spec; } -- (CGFloat)distanceToBaseline:(ASStackLayoutAlignItems)baselineAlignmentType -{ - return 0; -} - #pragma mark - Layout - (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize diff --git a/AsyncDisplayKit/Layout/ASStackLayoutSpec.mm b/AsyncDisplayKit/Layout/ASStackLayoutSpec.mm index 90d2cc7fd8..c5c3660fc4 100644 --- a/AsyncDisplayKit/Layout/ASStackLayoutSpec.mm +++ b/AsyncDisplayKit/Layout/ASStackLayoutSpec.mm @@ -26,8 +26,6 @@ { ASStackLayoutSpecStyle _style; std::vector> _children; - ASDN::RecursiveMutex _propertyLock; - CGFloat _distanceToBaseline; } + (instancetype)newWithStyle:(ASStackLayoutSpecStyle)style children:(NSArray *)children @@ -57,17 +55,9 @@ const CGSize finalSize = directionSize(_style.direction, unpositionedLayout.stackDimensionSum, positionedLayout.crossSize); NSArray *sublayouts = [NSArray arrayWithObjects:&positionedLayout.sublayouts[0] count:positionedLayout.sublayouts.size()]; - ASDN::MutexLocker l(_propertyLock); - _distanceToBaseline = positionedLayout.distanceToBaseline; - return [ASLayout newWithLayoutableObject:self size:ASSizeRangeClamp(constrainedSize, finalSize) sublayouts:sublayouts]; } -- (CGFloat)distanceToBaseline:(ASStackLayoutAlignItems)baselineAlignmentType -{ - return _distanceToBaseline; -} - @end diff --git a/AsyncDisplayKit/Layout/ASStackLayoutable.h b/AsyncDisplayKit/Layout/ASStackLayoutable.h index 643bed0382..057ca8b0fd 100644 --- a/AsyncDisplayKit/Layout/ASStackLayoutable.h +++ b/AsyncDisplayKit/Layout/ASStackLayoutable.h @@ -49,9 +49,11 @@ */ @property (nonatomic, readwrite) ASStackLayoutAlignSelf alignSelf; -/** - * @abstract Used for baseline alignment in stack spec. The distance from the top of the object to its baseline. - */ -- (CGFloat)distanceToBaseline:(ASStackLayoutAlignItems)baselineAlignmentType; +@end + +@protocol ASStackTextLayoutable + +@property (nonatomic, readwrite) CGFloat ascender; +@property (nonatomic, readwrite) CGFloat descender; @end diff --git a/AsyncDisplayKit/Layout/ASStackTextLayoutSpec.h b/AsyncDisplayKit/Layout/ASStackTextLayoutSpec.h new file mode 100644 index 0000000000..ab5b80db19 --- /dev/null +++ b/AsyncDisplayKit/Layout/ASStackTextLayoutSpec.h @@ -0,0 +1,36 @@ +// +// ASStackTextLayoutSpec.h +// AsyncDisplayKit +// +// Created by ricky cancro on 8/19/15. +// Copyright (c) 2015 Facebook. All rights reserved. +// + +#import + +/** Orientation of children along cross axis */ +typedef NS_ENUM(NSUInteger, ASStackTextLayoutBaselineAlignment) { + ASStackTextLayoutBaselineAlignmentNone, + /** Children align along the first baseline of the stack. Only available for horizontal stack nodes */ + ASStackTextLayoutBaselineAlignmentFirst, + /** Children align along the last baseline of the stack. Only available for horizontal stack nodes */ + ASStackTextLayoutBaselineAlignmentLast, +}; + + +typedef struct { + /** Specifies the direction children are stacked in. */ + ASStackLayoutSpecStyle stackLayoutStyle; + + ASStackTextLayoutBaselineAlignment baselineAlignment; +} ASStackTextLayoutSpecStyle; + +@interface ASStackTextLayoutSpec : ASLayoutSpec + +/** + @param style Specifies how children are laid out. + @param children ASLayoutable children to be positioned. + */ ++ (instancetype)newWithStyle:(ASStackTextLayoutSpecStyle)style children:(NSArray *)children; + +@end diff --git a/AsyncDisplayKit/Layout/ASStackTextLayoutSpec.mm b/AsyncDisplayKit/Layout/ASStackTextLayoutSpec.mm new file mode 100644 index 0000000000..a15f4c6686 --- /dev/null +++ b/AsyncDisplayKit/Layout/ASStackTextLayoutSpec.mm @@ -0,0 +1,127 @@ +// +// ASStackTextLayoutSpec.m +// AsyncDisplayKit +// +// Created by ricky cancro on 8/19/15. +// Copyright (c) 2015 Facebook. All rights reserved. +// + +#import "ASStackTextLayoutSpec.h" +#import "ASStackLayoutable.h" + +#import +#import + +#import "ASBaseDefines.h" +#import "ASInternalHelpers.h" + +#import "ASLayoutSpecUtilities.h" +#import "ASStackLayoutSpecUtilities.h" +#import "ASStackPositionedLayout.h" +#import "ASStackUnpositionedLayout.h" +#import "ASThread.h" + +static CGFloat baselineForItem(const ASStackTextLayoutSpecStyle &style, + const ASLayout *layout) { + + __weak id textChild = (id) layout.layoutableObject; + switch (style.baselineAlignment) { + case ASStackTextLayoutBaselineAlignmentNone: + return 0; + case ASStackTextLayoutBaselineAlignmentFirst: + return textChild.ascender; + case ASStackTextLayoutBaselineAlignmentLast: + return textChild.descender; + } + +} + +static CGFloat baselineOffset(const ASStackTextLayoutSpecStyle &style, + const ASLayout *l, + const CGFloat maxBaseline) +{ + switch (style.baselineAlignment) { + case ASStackTextLayoutBaselineAlignmentFirst: + case ASStackTextLayoutBaselineAlignmentLast: + return maxBaseline - baselineForItem(style, l); + case ASStackTextLayoutBaselineAlignmentNone: + return 0; + } +} + + +@implementation ASStackTextLayoutSpec +{ + ASStackTextLayoutSpecStyle _textStyle; + std::vector> _children; + std::vector> _stackChildren; + ASDN::RecursiveMutex _propertyLock; +} + ++ (instancetype)newWithStyle:(ASStackTextLayoutSpecStyle)style children:(NSArray *)children +{ + ASDisplayNodeAssert(style.stackLayoutStyle.direction == ASStackLayoutDirectionHorizontal && style.baselineAlignment != ASStackTextLayoutBaselineAlignmentNone, @"if you don't need baseline alignment, use ASStackLayoutSpec"); + + ASStackTextLayoutSpec *spec = [super new]; + if (spec) { + spec->_textStyle = style; + spec->_children = std::vector>(); + for (id child in children) { + ASDisplayNodeAssert([child conformsToProtocol:@protocol(ASStackTextLayoutable)], @"child must conform to ASStackLayoutable"); + + spec->_children.push_back(child); + spec->_stackChildren.push_back(child); + } + } + return spec; +} + ++ (instancetype)new +{ + ASDISPLAYNODE_NOT_DESIGNATED_INITIALIZER(); +} + +- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize +{ + ASStackLayoutSpecStyle stackStyle = _textStyle.stackLayoutStyle; + + + const auto unpositionedLayout = ASStackUnpositionedLayout::compute(_stackChildren, stackStyle, constrainedSize); + const auto positionedLayout = ASStackPositionedLayout::compute(unpositionedLayout, stackStyle, constrainedSize); + + // Alter the positioned layouts to include baselines + const auto baselineIt = std::max_element(positionedLayout.sublayouts.begin(), positionedLayout.sublayouts.end(), [&](const ASLayout *a, const ASLayout *b){ + return baselineForItem(_textStyle, a) < baselineForItem(_textStyle, b); + }); + const CGFloat maxBaseline = baselineIt == positionedLayout.sublayouts.end() ? 0 : baselineForItem(_textStyle, *baselineIt); + + CGPoint p = CGPointZero; + BOOL first = YES; + auto stackedChildren = AS::map(positionedLayout.sublayouts, [&](ASLayout *l) -> ASLayout *{ + __weak id textChild = (id) l.layoutableObject; + if (first) { + p = l.position; + } + first = NO; + + if (stackStyle.direction == ASStackLayoutDirectionHorizontal) { + l.position = p + CGPointMake(0, baselineOffset(_textStyle, l, maxBaseline)); + } + + CGFloat spacingAfterBaseline = (stackStyle.direction == ASStackLayoutDirectionVertical) ? textChild.descender : 0; + p = p + directionPoint(stackStyle.direction, stackDimension(stackStyle.direction, l.size) + [(id)l.layoutableObject spacingAfter] + spacingAfterBaseline, 0); + + return l; + }); + + const ASStackPositionedLayout alteredPositionedLayouts = {stackedChildren, positionedLayout.crossSize}; + const CGSize finalSize = directionSize(stackStyle.direction, unpositionedLayout.stackDimensionSum, alteredPositionedLayouts.crossSize); + + NSArray *sublayouts = [NSArray arrayWithObjects:&alteredPositionedLayouts.sublayouts[0] count:alteredPositionedLayouts.sublayouts.size()]; + + + return [ASLayout newWithLayoutableObject:self + size:ASSizeRangeClamp(constrainedSize, finalSize) + sublayouts:sublayouts]; +} +@end diff --git a/AsyncDisplayKit/Private/ASStackPositionedLayout.h b/AsyncDisplayKit/Private/ASStackPositionedLayout.h index ea9f56fd26..211bda5b11 100644 --- a/AsyncDisplayKit/Private/ASStackPositionedLayout.h +++ b/AsyncDisplayKit/Private/ASStackPositionedLayout.h @@ -17,7 +17,6 @@ struct ASStackPositionedLayout { const std::vector sublayouts; const CGFloat crossSize; - const CGFloat distanceToBaseline; /** Given an unpositioned layout, computes the positions each child should be placed at. */ static ASStackPositionedLayout compute(const ASStackUnpositionedLayout &unpositionedLayout, diff --git a/AsyncDisplayKit/Private/ASStackPositionedLayout.mm b/AsyncDisplayKit/Private/ASStackPositionedLayout.mm index 1e667abd73..b567be3ef7 100644 --- a/AsyncDisplayKit/Private/ASStackPositionedLayout.mm +++ b/AsyncDisplayKit/Private/ASStackPositionedLayout.mm @@ -18,8 +18,10 @@ static CGFloat baselineForItem(const ASStackLayoutSpecStyle &style, const ASStackUnpositionedItem &item) { const ASStackLayoutAlignItems alignItems = alignment(item.child.alignSelf, style.alignItems); - if (alignItems == ASStackLayoutAlignItemsFirstBaseline || alignItems == ASStackLayoutAlignItemsLastBaseline) { - return [item.child distanceToBaseline:alignItems]; + if (alignItems == ASStackLayoutAlignItemsFirstBaseline) { + return item.child.layoutInsets.top; + } else if (alignItems == ASStackLayoutAlignItemsLastBaseline) { + return item.child.layoutInsets.bottom; } return 0; } @@ -75,11 +77,11 @@ static ASStackPositionedLayout stackedLayout(const ASStackLayoutSpecStyle &style first = NO; l.layout.position = p + directionPoint(style.direction, 0, crossOffset(style, l, crossSize, maxBaseline)); - CGFloat spacingAfterBaseline = (style.direction == ASStackLayoutDirectionVertical && style.baselineRelativeArrangement) ? l.layout.size.height - [l.child distanceToBaseline:style.alignItems] : 0; + CGFloat spacingAfterBaseline = (style.direction == ASStackLayoutDirectionVertical && style.baselineRelativeArrangement) ? l.child.layoutInsets.bottom : 0; p = p + directionPoint(style.direction, stackDimension(style.direction, l.layout.size) + l.child.spacingAfter + spacingAfterBaseline, 0); return l.layout; }); - return {stackedChildren, crossSize, maxBaseline}; + return {stackedChildren, crossSize}; } ASStackPositionedLayout ASStackPositionedLayout::compute(const ASStackUnpositionedLayout &unpositionedLayout,