Merge pull request #611 from rcancro/baseline

Added baseline alignment for ASStackLayoutSpec.  Break up ASLayoutable into common, stack, and baseline protocol.
This commit is contained in:
appleguy 2015-08-24 14:26:33 -07:00
commit 9c51bde8e8
19 changed files with 541 additions and 103 deletions

View File

@ -217,6 +217,18 @@
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, ); }; };
9C204A641B86349B00313849 /* ASBaselinePositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C204A621B86349B00313849 /* ASBaselinePositionedLayout.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C204A651B86349B00313849 /* ASBaselinePositionedLayout.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C204A621B86349B00313849 /* ASBaselinePositionedLayout.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C204A661B86349B00313849 /* ASBaselinePositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C204A631B86349B00313849 /* ASBaselinePositionedLayout.mm */; };
9C204A671B86349B00313849 /* ASBaselinePositionedLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C204A631B86349B00313849 /* ASBaselinePositionedLayout.mm */; };
9C204A6A1B87803A00313849 /* ASBaselineLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C204A681B87803A00313849 /* ASBaselineLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C204A6B1B87803A00313849 /* ASBaselineLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C204A681B87803A00313849 /* ASBaselineLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C3061061B857EC400D0530B /* ASBaselineLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C3061041B857EC400D0530B /* ASBaselineLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C3061071B857EC400D0530B /* ASBaselineLayoutSpec.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C3061041B857EC400D0530B /* ASBaselineLayoutSpec.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C3061081B857EC400D0530B /* ASBaselineLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C3061051B857EC400D0530B /* ASBaselineLayoutSpec.mm */; };
9C3061091B857EC400D0530B /* ASBaselineLayoutSpec.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C3061051B857EC400D0530B /* ASBaselineLayoutSpec.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 */; };
AC21EC101B3D0BF600C8B19A /* ASStackLayoutDefines.h in Headers */ = {isa = PBXBuildFile; fileRef = AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */; settings = {ATTRIBUTES = (Public, ); }; };
AC3C4A511A1139C100143C57 /* ASCollectionView.h in Headers */ = {isa = PBXBuildFile; fileRef = AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -445,15 +457,15 @@
058D09D5195D050800B7D73C /* ASControlNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASControlNode.h; sourceTree = "<group>"; };
058D09D6195D050800B7D73C /* ASControlNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASControlNode.m; sourceTree = "<group>"; };
058D09D7195D050800B7D73C /* ASControlNode+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASControlNode+Subclasses.h"; sourceTree = "<group>"; };
058D09D8195D050800B7D73C /* ASDisplayNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ASDisplayNode.h; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
058D09D8195D050800B7D73C /* ASDisplayNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = ASDisplayNode.h; sourceTree = "<group>"; };
058D09D9195D050800B7D73C /* ASDisplayNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASDisplayNode.mm; sourceTree = "<group>"; };
058D09DA195D050800B7D73C /* ASDisplayNode+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "ASDisplayNode+Subclasses.h"; sourceTree = "<group>"; };
058D09DA195D050800B7D73C /* ASDisplayNode+Subclasses.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = "ASDisplayNode+Subclasses.h"; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
058D09DB195D050800B7D73C /* ASDisplayNodeExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASDisplayNodeExtras.h; sourceTree = "<group>"; };
058D09DC195D050800B7D73C /* ASDisplayNodeExtras.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASDisplayNodeExtras.mm; sourceTree = "<group>"; };
058D09DD195D050800B7D73C /* ASImageNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASImageNode.h; sourceTree = "<group>"; };
058D09DE195D050800B7D73C /* ASImageNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASImageNode.mm; sourceTree = "<group>"; };
058D09DF195D050800B7D73C /* ASTextNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASTextNode.h; sourceTree = "<group>"; };
058D09E0195D050800B7D73C /* ASTextNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASTextNode.mm; sourceTree = "<group>"; };
058D09E0195D050800B7D73C /* ASTextNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASTextNode.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
058D09E2195D050800B7D73C /* _ASDisplayLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASDisplayLayer.h; sourceTree = "<group>"; };
058D09E3195D050800B7D73C /* _ASDisplayLayer.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = _ASDisplayLayer.mm; sourceTree = "<group>"; };
058D09E4195D050800B7D73C /* _ASDisplayView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASDisplayView.h; sourceTree = "<group>"; };
@ -556,6 +568,12 @@
4640521E1A3F83C40061C0BA /* ASMultidimensionalArrayUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASMultidimensionalArrayUtils.h; sourceTree = "<group>"; };
4640521F1A3F83C40061C0BA /* ASMultidimensionalArrayUtils.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASMultidimensionalArrayUtils.mm; sourceTree = "<group>"; };
6BDC61F51978FEA400E50D21 /* AsyncDisplayKit.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AsyncDisplayKit.h; sourceTree = "<group>"; };
9C204A621B86349B00313849 /* ASBaselinePositionedLayout.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASBaselinePositionedLayout.h; sourceTree = "<group>"; };
9C204A631B86349B00313849 /* ASBaselinePositionedLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASBaselinePositionedLayout.mm; sourceTree = "<group>"; };
9C204A681B87803A00313849 /* ASBaselineLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASBaselineLayoutable.h; path = AsyncDisplayKit/Layout/ASBaselineLayoutable.h; sourceTree = "<group>"; };
9C3061041B857EC400D0530B /* ASBaselineLayoutSpec.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASBaselineLayoutSpec.h; path = AsyncDisplayKit/Layout/ASBaselineLayoutSpec.h; sourceTree = "<group>"; };
9C3061051B857EC400D0530B /* ASBaselineLayoutSpec.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASBaselineLayoutSpec.mm; path = AsyncDisplayKit/Layout/ASBaselineLayoutSpec.mm; sourceTree = "<group>"; };
9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutable.h; path = AsyncDisplayKit/Layout/ASStackLayoutable.h; sourceTree = "<group>"; };
9F06E5CC1B4CAF4200F015D8 /* ASCollectionViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASCollectionViewTests.m; sourceTree = "<group>"; };
AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStackLayoutDefines.h; path = AsyncDisplayKit/Layout/ASStackLayoutDefines.h; sourceTree = "<group>"; };
AC3C4A4F1A1139C100143C57 /* ASCollectionView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASCollectionView.h; sourceTree = "<group>"; };
@ -921,6 +939,8 @@
ACF6ED481B17847A00DA7C62 /* ASStackPositionedLayout.mm */,
ACF6ED491B17847A00DA7C62 /* ASStackUnpositionedLayout.h */,
ACF6ED4A1B17847A00DA7C62 /* ASStackUnpositionedLayout.mm */,
9C204A621B86349B00313849 /* ASBaselinePositionedLayout.h */,
9C204A631B86349B00313849 /* ASBaselinePositionedLayout.mm */,
);
path = Private;
sourceTree = "<group>";
@ -943,6 +963,7 @@
children = (
ACF6ED011B17843500DA7C62 /* ASBackgroundLayoutSpec.h */,
ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutSpec.mm */,
9C204A681B87803A00313849 /* ASBaselineLayoutable.h */,
ACF6ED031B17843500DA7C62 /* ASCenterLayoutSpec.h */,
ACF6ED041B17843500DA7C62 /* ASCenterLayoutSpec.mm */,
ACF6ED071B17843500DA7C62 /* ASDimension.h */,
@ -960,11 +981,14 @@
ACF6ED131B17843500DA7C62 /* ASOverlayLayoutSpec.mm */,
ACF6ED141B17843500DA7C62 /* ASRatioLayoutSpec.h */,
ACF6ED151B17843500DA7C62 /* ASRatioLayoutSpec.mm */,
9C49C36E1B853957000B0DD5 /* ASStackLayoutable.h */,
AC21EC0F1B3D0BF600C8B19A /* ASStackLayoutDefines.h */,
ACF6ED161B17843500DA7C62 /* ASStackLayoutSpec.h */,
ACF6ED171B17843500DA7C62 /* ASStackLayoutSpec.mm */,
ACF6ED181B17843500DA7C62 /* ASStaticLayoutSpec.h */,
ACF6ED191B17843500DA7C62 /* ASStaticLayoutSpec.mm */,
9C3061041B857EC400D0530B /* ASBaselineLayoutSpec.h */,
9C3061051B857EC400D0530B /* ASBaselineLayoutSpec.mm */,
);
name = Layout;
path = ..;
@ -1006,6 +1030,7 @@
files = (
AC21EC101B3D0BF600C8B19A /* ASStackLayoutDefines.h in Headers */,
AC47D9451B3BB41900AAEE9D /* ASRelativeSize.h in Headers */,
9C49C36F1B853957000B0DD5 /* ASStackLayoutable.h in Headers */,
ACF6ED511B17847A00DA7C62 /* ASStackUnpositionedLayout.h in Headers */,
ACF6ED2D1B17843500DA7C62 /* ASRatioLayoutSpec.h in Headers */,
ACF6ED261B17843500DA7C62 /* ASLayoutSpec.h in Headers */,
@ -1024,6 +1049,7 @@
464052201A3F83C40061C0BA /* ASDataController.h in Headers */,
05A6D05A19D0EB64002DD95E /* ASDealloc2MainObject.h in Headers */,
0516FA401A1563D200B4EBED /* ASMultiplexImageNode.h in Headers */,
9C204A6A1B87803A00313849 /* ASBaselineLayoutable.h in Headers */,
058D0A47195D05CB00B7D73C /* ASControlNode.h in Headers */,
058D0A48195D05CB00B7D73C /* ASControlNode.m in Headers */,
058D0A49195D05CB00B7D73C /* ASControlNode+Subclasses.h in Headers */,
@ -1045,6 +1071,7 @@
0574D5E219C110940097DC25 /* ASTableViewProtocols.h in Headers */,
055F1A3C19ABD43F004DAFF1 /* ASCellNode.h in Headers */,
058D0A53195D05DC00B7D73C /* _ASDisplayLayer.h in Headers */,
9C204A641B86349B00313849 /* ASBaselinePositionedLayout.h in Headers */,
058D0A54195D05DC00B7D73C /* _ASDisplayLayer.mm in Headers */,
058D0A55195D05DC00B7D73C /* _ASDisplayView.h in Headers */,
058D0A56195D05DC00B7D73C /* _ASDisplayView.mm in Headers */,
@ -1071,6 +1098,7 @@
058D0A67195D05DC00B7D73C /* NSMutableAttributedString+TextKitAdditions.m in Headers */,
058D0A68195D05EC00B7D73C /* _ASAsyncTransaction.h in Headers */,
205F0E0F1B371875007741D0 /* UICollectionViewLayout+ASConvenience.h in Headers */,
9C3061061B857EC400D0530B /* ASBaselineLayoutSpec.h in Headers */,
058D0A69195D05EC00B7D73C /* _ASAsyncTransaction.m in Headers */,
058D0A6A195D05EC00B7D73C /* _ASAsyncTransactionContainer+Private.h in Headers */,
058D0A6B195D05EC00B7D73C /* _ASAsyncTransactionContainer.h in Headers */,
@ -1136,6 +1164,7 @@
B35061FA1B010EFD0018CF92 /* ASControlNode+Subclasses.h in Headers */,
B35062371B010EFD0018CF92 /* ASTextNodeWordKerner.h in Headers */,
B35062261B010EFD0018CF92 /* ASRangeController.h in Headers */,
9C204A651B86349B00313849 /* ASBaselinePositionedLayout.h in Headers */,
B35062111B010EFD0018CF92 /* _ASDisplayView.h in Headers */,
B35061F81B010EFD0018CF92 /* ASControlNode.h in Headers */,
430E7C901B4C23F100697A4C /* ASIndexPath.h in Headers */,
@ -1145,6 +1174,7 @@
B35061F31B010EFD0018CF92 /* ASCellNode.h in Headers */,
34EFC76C1B701CED00AD841F /* ASOverlayLayoutSpec.h in Headers */,
B35062201B010EFD0018CF92 /* ASLayoutController.h in Headers */,
9C3061071B857EC400D0530B /* ASBaselineLayoutSpec.h in Headers */,
B35062571B010F070018CF92 /* ASAssert.h in Headers */,
B35062411B010EFD0018CF92 /* _ASAsyncTransactionGroup.h in Headers */,
B350623C1B010EFD0018CF92 /* _ASAsyncTransaction.h in Headers */,
@ -1172,6 +1202,7 @@
B350620C1B010EFD0018CF92 /* ASTableViewProtocols.h in Headers */,
B35062481B010EFD0018CF92 /* _AS-objc-internal.h in Headers */,
B350623F1B010EFD0018CF92 /* _ASAsyncTransactionContainer.h in Headers */,
9C49C3701B853961000B0DD5 /* ASStackLayoutable.h in Headers */,
34EFC7731B701D0700AD841F /* ASStaticLayoutSpec.h in Headers */,
B35062081B010EFD0018CF92 /* ASScrollNode.h in Headers */,
B35061F51B010EFD0018CF92 /* ASCollectionView.h in Headers */,
@ -1187,6 +1218,7 @@
34EFC7631B701CBF00AD841F /* ASCenterLayoutSpec.h in Headers */,
B350624D1B010EFD0018CF92 /* _ASScopeTimer.h in Headers */,
34EFC7701B701CFA00AD841F /* ASStackLayoutDefines.h in Headers */,
9C204A6B1B87803A00313849 /* ASBaselineLayoutable.h in Headers */,
509E68651B3AEDC5009B9150 /* CGRect+ASConvenience.h in Headers */,
B350624F1B010EFD0018CF92 /* ASDisplayNode+DebugTiming.h in Headers */,
B35062211B010EFD0018CF92 /* ASLayoutRangeType.h in Headers */,
@ -1409,6 +1441,7 @@
058D0A26195D050800B7D73C /* _ASCoreAnimationExtras.mm in Sources */,
058D0A23195D050800B7D73C /* _ASAsyncTransactionContainer.m in Sources */,
058D0A1E195D050800B7D73C /* ASTextNodeShadower.m in Sources */,
9C204A661B86349B00313849 /* ASBaselinePositionedLayout.mm in Sources */,
ACF6ED2E1B17843500DA7C62 /* ASRatioLayoutSpec.mm in Sources */,
058D0A18195D050800B7D73C /* _ASDisplayLayer.mm in Sources */,
ACF6ED321B17843500DA7C62 /* ASStaticLayoutSpec.mm in Sources */,
@ -1447,6 +1480,7 @@
0549634A1A1EA066000F8E56 /* ASBasicImageDownloader.mm in Sources */,
058D0A14195D050800B7D73C /* ASDisplayNode.mm in Sources */,
058D0A1B195D050800B7D73C /* ASMutableAttributedStringBuilder.m in Sources */,
9C3061081B857EC400D0530B /* ASBaselineLayoutSpec.mm in Sources */,
058D0A2B195D050800B7D73C /* ASImageNode+CGExtras.m in Sources */,
058D0A24195D050800B7D73C /* _ASAsyncTransactionGroup.m in Sources */,
058D0A1C195D050800B7D73C /* ASTextNodeCoreTextAdditions.m in Sources */,
@ -1508,8 +1542,10 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
9C3061091B857EC400D0530B /* ASBaselineLayoutSpec.mm in Sources */,
34EFC7641B701CC600AD841F /* ASCenterLayoutSpec.mm in Sources */,
B350623B1B010EFD0018CF92 /* NSMutableAttributedString+TextKitAdditions.m in Sources */,
9C204A671B86349B00313849 /* ASBaselinePositionedLayout.mm in Sources */,
B35062401B010EFD0018CF92 /* _ASAsyncTransactionContainer.m in Sources */,
B35062311B010EFD0018CF92 /* ASTextNodeRenderer.mm in Sources */,
B35062051B010EFD0018CF92 /* ASMultiplexImageNode.mm in Sources */,

View File

@ -13,7 +13,7 @@
#import <AsyncDisplayKit/ASDealloc2MainObject.h>
#import <AsyncDisplayKit/ASDimension.h>
#import <AsyncDisplayKit/ASLayoutable.h>
#import <AsyncDisplayKit/ASStackLayoutable.h>
/**
* UIView creation block. Used to create the backing view of a new display node.
@ -40,7 +40,7 @@ typedef CALayer *(^ASDisplayNodeLayerBlock)();
*
*/
@interface ASDisplayNode : ASDealloc2MainObject <ASLayoutable>
@interface ASDisplayNode : ASDealloc2MainObject <ASStackLayoutable>
/** @name Initializing a node object */

View File

@ -7,7 +7,7 @@
*/
#import <AsyncDisplayKit/ASControlNode.h>
#import <AsyncDisplayKit/ASBaselineLayoutable.h>
@protocol ASTextNodeDelegate;
@ -30,7 +30,7 @@ typedef NS_ENUM(NSUInteger, ASTextNodeHighlightStyle) {
@abstract Draws interactive rich text.
@discussion Backed by TextKit.
*/
@interface ASTextNode : ASControlNode
@interface ASTextNode : ASControlNode <ASBaselineLayoutable>
/**
@abstract The attributed string to show.

View File

@ -17,6 +17,7 @@
#import <AsyncDisplayKit/ASTextNodeTextKitHelpers.h>
#import <AsyncDisplayKit/ASDisplayNodeExtras.h>
#import "ASInternalHelpers.h"
#import "ASTextNodeRenderer.h"
#import "ASTextNodeShadower.h"
@ -107,6 +108,9 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
UILongPressGestureRecognizer *_longPressGestureRecognizer;
}
@synthesize ascender = _ascender;
@synthesize descender = _descender;
#pragma mark - NSObject
- (instancetype)init
@ -355,6 +359,9 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
self.isAccessibilityElement = YES;
}
});
_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

View File

@ -0,0 +1,63 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import <AsyncDisplayKit/ASStackLayoutSpec.h>
#import <AsyncDisplayKit/ASBaselineLayoutable.h>
typedef NS_ENUM(NSUInteger, ASBaselineLayoutBaselineAlignment) {
/** No baseline alignment. This is only valid for a vertical stack */
ASBaselineLayoutBaselineAlignmentNone,
/** Align all children to the first baseline. This is only valid for a horizontal stack */
ASBaselineLayoutBaselineAlignmentFirst,
/** Align all children to the last baseline. This is useful when a text node wraps and you want to align
to the bottom baseline. This is only valid for a horizontal stack */
ASBaselineLayoutBaselineAlignmentLast,
};
/**
A specialized version of a stack layout that aligns its children on a baseline. This spec only works with
ASBaselineLayoutable children.
If the spec is created with a horizontal direction, the children will be laid on a common baseline.
If the spec is created with a vertical direction, a child's vertical spacing will be measured from its
baseline instead of from the child's bounding box.
*/
@interface ASBaselineLayoutSpec : ASLayoutSpec <ASBaselineLayoutable>
/** Specifies the direction children are stacked in. */
@property (nonatomic, assign) ASStackLayoutDirection direction;
/** The amount of space between each child. */
@property (nonatomic, assign) CGFloat spacing;
/** The amount of space between each child. */
@property (nonatomic, assign) ASStackLayoutJustifyContent justifyContent;
/** Orientation of children along cross axis */
@property (nonatomic, assign) ASStackLayoutAlignItems alignItems;
/** The type of baseline alignment */
@property (nonatomic, assign) ASBaselineLayoutBaselineAlignment baselineAlignment;
- (void)addChild:(id<ASBaselineLayoutable>)child;
- (void)addChildren:(NSArray *)children;
/**
@param direction The direction of the stack view (horizontal or vertical)
@param spacing The spacing between the children
@param baselineAlignment The baseline to align to
@param justifyContent If no children are flexible, this describes how to fill any extra space
@param alignItems Orientation of the children along the cross axis
@param children ASLayoutable children to be positioned.
*/
+ (instancetype)baselineLayoutSpecWithDirection:(ASStackLayoutDirection)direction
spacing:(CGFloat)spacing
baselineAlignment:(ASBaselineLayoutBaselineAlignment)baselineAlignment
justifyContent:(ASStackLayoutJustifyContent)justifyContent
alignItems:(ASStackLayoutAlignItems)alignItems
children:(NSArray *)children;
@end

View File

@ -0,0 +1,97 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import "ASBaselineLayoutSpec.h"
#import "ASStackLayoutable.h"
#import <numeric>
#import <vector>
#import "ASBaseDefines.h"
#import "ASInternalHelpers.h"
#import "ASLayoutSpecUtilities.h"
#import "ASStackLayoutSpecUtilities.h"
#import "ASStackPositionedLayout.h"
#import "ASStackUnpositionedLayout.h"
#import "ASBaselinePositionedLayout.h"
#import "ASThread.h"
@implementation ASBaselineLayoutSpec
{
std::vector<id<ASStackLayoutable>> _children;
ASDN::RecursiveMutex _propertyLock;
}
@synthesize ascender = _ascender;
@synthesize descender = _descender;
- (instancetype)initWithDirection:(ASStackLayoutDirection)direction spacing:(CGFloat)spacing baselineAlignment:(ASBaselineLayoutBaselineAlignment)baselineAlignment justifyContent:(ASStackLayoutJustifyContent)justifyContent alignItems:(ASStackLayoutAlignItems)alignItems children:(NSArray *)children
{
if (!(self = [super init])) {
return nil;
}
ASDisplayNodeAssert((direction == ASStackLayoutDirectionHorizontal && baselineAlignment != ASBaselineLayoutBaselineAlignmentNone) || direction == ASStackLayoutDirectionVertical, @"baselineAlignment is set to none. If you don't need baseline alignment please use ASStackLayoutSpec");
_direction = direction;
_alignItems = alignItems;
_spacing = spacing;
_justifyContent = justifyContent;
_baselineAlignment = baselineAlignment;
_children = std::vector<id<ASStackLayoutable>>();
for (id<ASStackLayoutable> child in children) {
_children.push_back(child);
}
return self;
}
+ (instancetype)baselineLayoutSpecWithDirection:(ASStackLayoutDirection)direction spacing:(CGFloat)spacing baselineAlignment:(ASBaselineLayoutBaselineAlignment)baselineAlignment justifyContent:(ASStackLayoutJustifyContent)justifyContent alignItems:(ASStackLayoutAlignItems)alignItems children:(NSArray *)children
{
return [[ASBaselineLayoutSpec alloc] initWithDirection:direction spacing:spacing baselineAlignment:baselineAlignment justifyContent:justifyContent alignItems:alignItems children:children];
}
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
{
ASStackLayoutSpecStyle stackStyle = {.direction = _direction, .spacing = _spacing, .justifyContent = _justifyContent, .alignItems = _alignItems};
ASBaselineLayoutSpecStyle style = { .baselineAlignment = _baselineAlignment, .stackLayoutStyle = stackStyle };
const auto unpositionedLayout = ASStackUnpositionedLayout::compute(_children, stackStyle, constrainedSize);
const auto positionedLayout = ASStackPositionedLayout::compute(unpositionedLayout, stackStyle, constrainedSize);
const auto baselinePositionedLayout = ASBaselinePositionedLayout::compute(positionedLayout, style, constrainedSize);
const CGSize finalSize = directionSize(stackStyle.direction, unpositionedLayout.stackDimensionSum, baselinePositionedLayout.crossSize);
NSArray *sublayouts = [NSArray arrayWithObjects:&baselinePositionedLayout.sublayouts[0] count:baselinePositionedLayout.sublayouts.size()];
ASDN::MutexLocker l(_propertyLock);
_ascender = baselinePositionedLayout.ascender;
_descender = baselinePositionedLayout.descender;
return [ASLayout layoutWithLayoutableObject:self
size:ASSizeRangeClamp(constrainedSize, finalSize)
sublayouts:sublayouts];
}
- (void)addChild:(id<ASBaselineLayoutable>)child
{
_children.push_back(child);
}
- (void)addChildren:(NSArray *)children
{
for (id<ASBaselineLayoutable> child in children) {
[self addChild:child];
}
}
@end

View File

@ -0,0 +1,23 @@
/* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*/
#import "ASStackLayoutable.h"
@protocol ASBaselineLayoutable <ASStackLayoutable>
/**
* @abstract The distance from the top of the layoutable object to its baseline
*/
@property (nonatomic, readwrite) CGFloat ascender;
/**
* @abstract The distance from the bottom of the layoutable object to its baseline
*/
@property (nonatomic, readwrite) CGFloat descender;
@end

View File

@ -8,10 +8,10 @@
*
*/
#import <AsyncDisplayKit/ASLayoutable.h>
#import <AsyncDisplayKit/ASStackLayoutable.h>
/** A layout spec is an temporarly mutable object that describes a layout, loosely inspired by React. */
@interface ASLayoutSpec : NSObject <ASLayoutable>
/** A layout spec is an immutable object that describes a layout, loosely inspired by React. */
@interface ASLayoutSpec : NSObject <ASStackLayoutable>
/**
Creation of a layout spec should only happen by a user in layoutSpecThatFits:. During that method, a

View File

@ -20,43 +20,6 @@
*/
@protocol ASLayoutable <NSObject>
/**
* @abstract Additional space to place before this object in the stacking direction.
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) CGFloat spacingBefore;
/**
* @abstract Additional space to place after this object in the stacking direction.
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) CGFloat spacingAfter;
/**
* @abstract If the sum of childrens' stack dimensions is less than the minimum size, should this object grow?
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) BOOL flexGrow;
/**
* @abstract If the sum of childrens' stack dimensions is greater than the maximum size, should this object shrink?
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) BOOL flexShrink;
/**
* @abstract Specifies the initial size in the stack dimension for this object.
* Default to ASRelativeDimensionUnconstrained.
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) ASRelativeDimension flexBasis;
/**
* @abstract Orientation of the object along cross axis, overriding alignItems
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) ASStackLayoutAlignSelf alignSelf;
/**
* @abstract Calculate a layout based on given size range.
*

View File

@ -8,6 +8,45 @@
*
*/
/** The direction children are stacked in */
typedef NS_ENUM(NSUInteger, ASStackLayoutDirection) {
/** Children are stacked vertically */
ASStackLayoutDirectionVertical,
/** Children are stacked horizontally */
ASStackLayoutDirectionHorizontal,
};
/** If no children are flexible, how should this spec justify its children in the available space? */
typedef NS_ENUM(NSUInteger, ASStackLayoutJustifyContent) {
/**
On overflow, children overflow out of this spec's bounds on the right/bottom side.
On underflow, children are left/top-aligned within this spec's bounds.
*/
ASStackLayoutJustifyContentStart,
/**
On overflow, children are centered and overflow on both sides.
On underflow, children are centered within this spec's bounds in the stacking direction.
*/
ASStackLayoutJustifyContentCenter,
/**
On overflow, children overflow out of this spec's bounds on the left/top side.
On underflow, children are right/bottom-aligned within this spec's bounds.
*/
ASStackLayoutJustifyContentEnd,
};
/** Orientation of children along cross axis */
typedef NS_ENUM(NSUInteger, ASStackLayoutAlignItems) {
/** Align children to start of cross axis */
ASStackLayoutAlignItemsStart,
/** Align children with end of cross axis */
ASStackLayoutAlignItemsEnd,
/** Center children on cross axis */
ASStackLayoutAlignItemsCenter,
/** Expand children to fill cross axis */
ASStackLayoutAlignItemsStretch
};
/**
Each child may override their parent stack's cross axis alignment.
@see ASStackLayoutAlignItems

View File

@ -9,45 +9,7 @@
*/
#import <AsyncDisplayKit/ASLayoutSpec.h>
/** The direction children are stacked in */
typedef NS_ENUM(NSUInteger, ASStackLayoutDirection) {
/** Children are stacked vertically */
ASStackLayoutDirectionVertical,
/** Children are stacked horizontally */
ASStackLayoutDirectionHorizontal,
};
/** If no children are flexible, how should this spec justify its children in the available space? */
typedef NS_ENUM(NSUInteger, ASStackLayoutJustifyContent) {
/**
On overflow, children overflow out of this spec's bounds on the right/bottom side.
On underflow, children are left/top-aligned within this spec's bounds.
*/
ASStackLayoutJustifyContentStart,
/**
On overflow, children are centered and overflow on both sides.
On underflow, children are centered within this spec's bounds in the stacking direction.
*/
ASStackLayoutJustifyContentCenter,
/**
On overflow, children overflow out of this spec's bounds on the left/top side.
On underflow, children are right/bottom-aligned within this spec's bounds.
*/
ASStackLayoutJustifyContentEnd,
};
/** Orientation of children along cross axis */
typedef NS_ENUM(NSUInteger, ASStackLayoutAlignItems) {
/** Align children to start of cross axis */
ASStackLayoutAlignItemsStart,
/** Align children with end of cross axis */
ASStackLayoutAlignItemsEnd,
/** Center children on cross axis */
ASStackLayoutAlignItemsCenter,
/** Expand children to fill cross axis */
ASStackLayoutAlignItemsStretch,
};
#import <AsyncDisplayKit/ASStackLayoutDefines.h>
/**
@ -93,7 +55,7 @@ typedef NS_ENUM(NSUInteger, ASStackLayoutAlignItems) {
*/
+ (instancetype)stackLayoutSpecWithDirection:(ASStackLayoutDirection)direction spacing:(CGFloat)spacing justifyContent:(ASStackLayoutJustifyContent)justifyContent alignItems:(ASStackLayoutAlignItems)alignItems children:(NSArray *)children;
- (void)addChild:(id<ASLayoutable>)child;
- (void)addChild:(id<ASStackLayoutable>)child;
- (void)addChildren:(NSArray *)children;
@end

View File

@ -20,10 +20,11 @@
#import "ASStackLayoutSpecUtilities.h"
#import "ASStackPositionedLayout.h"
#import "ASStackUnpositionedLayout.h"
#import "ASThread.h"
@implementation ASStackLayoutSpec
{
std::vector<id<ASLayoutable>> _children;
std::vector<id<ASStackLayoutable>> _children;
}
- (instancetype)init
@ -46,14 +47,14 @@
_spacing = spacing;
_justifyContent = justifyContent;
_children = std::vector<id<ASLayoutable>>();
for (id<ASLayoutable> child in children) {
_children = std::vector<id<ASStackLayoutable>>();
for (id<ASStackLayoutable> child in children) {
_children.push_back(child);
}
return self;
}
- (void)addChild:(id<ASLayoutable>)child
- (void)addChild:(id<ASStackLayoutable>)child
{
ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable");
_children.push_back(child);
@ -61,7 +62,7 @@
- (void)addChildren:(NSArray *)children
{
for (id<ASLayoutable> child in children) {
for (id<ASStackLayoutable> child in children) {
[self addChild:child];
}
}

View File

@ -0,0 +1,52 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import <AsyncDisplayKit/ASLayoutable.h>
@protocol ASStackLayoutable <ASLayoutable>
/**
* @abstract Additional space to place before this object in the stacking direction.
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) CGFloat spacingBefore;
/**
* @abstract Additional space to place after this object in the stacking direction.
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) CGFloat spacingAfter;
/**
* @abstract If the sum of childrens' stack dimensions is less than the minimum size, should this object grow?
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) BOOL flexGrow;
/**
* @abstract If the sum of childrens' stack dimensions is greater than the maximum size, should this object shrink?
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) BOOL flexShrink;
/**
* @abstract Specifies the initial size in the stack dimension for this object.
* Default to ASRelativeDimensionUnconstrained.
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) ASRelativeDimension flexBasis;
/**
* @abstract Orientation of the object along cross axis, overriding alignItems
* Used when attached to a stack layout.
*/
@property (nonatomic, readwrite) ASStackLayoutAlignSelf alignSelf;
@end

View File

@ -0,0 +1,34 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import "ASLayout.h"
#import "ASDimension.h"
#import "ASBaselineLayoutSpec.h"
#import "ASStackPositionedLayout.h"
typedef struct {
/** Describes how the stack will be laid out */
ASStackLayoutSpecStyle stackLayoutStyle;
/** The type of baseline alignment */
ASBaselineLayoutBaselineAlignment baselineAlignment;
} ASBaselineLayoutSpecStyle;
struct ASBaselinePositionedLayout {
const std::vector<ASLayout *> sublayouts;
const CGFloat crossSize;
const CGFloat ascender;
const CGFloat descender;
/** Given a positioned layout, computes each child position using baseline alignment. */
static ASBaselinePositionedLayout compute(const ASStackPositionedLayout &positionedLayout,
const ASBaselineLayoutSpecStyle &style,
const ASSizeRange &constrainedSize);
};

View File

@ -0,0 +1,162 @@
/*
* Copyright (c) 2014-present, Facebook, Inc.
* All rights reserved.
*
* This source code is licensed under the BSD-style license found in the
* LICENSE file in the root directory of this source tree. An additional grant
* of patent rights can be found in the PATENTS file in the same directory.
*
*/
#import "ASBaselinePositionedLayout.h"
#import "ASLayoutSpecUtilities.h"
#import "ASStackLayoutSpecUtilities.h"
static CGFloat baselineForItem(const ASBaselineLayoutSpecStyle &style,
const ASLayout *layout) {
__weak id<ASBaselineLayoutable> child = (id<ASBaselineLayoutable>) layout.layoutableObject;
switch (style.baselineAlignment) {
case ASBaselineLayoutBaselineAlignmentNone:
return 0;
case ASBaselineLayoutBaselineAlignmentFirst:
return child.ascender;
case ASBaselineLayoutBaselineAlignmentLast:
return layout.size.height + child.descender;
}
}
static CGFloat baselineOffset(const ASBaselineLayoutSpecStyle &style,
const ASLayout *l,
const CGFloat maxAscender,
const CGFloat maxBaseline)
{
if (style.stackLayoutStyle.direction == ASStackLayoutDirectionHorizontal) {
__weak id<ASBaselineLayoutable> child = (id<ASBaselineLayoutable>)l.layoutableObject;
switch (style.baselineAlignment) {
case ASBaselineLayoutBaselineAlignmentFirst:
return maxAscender - child.ascender;
case ASBaselineLayoutBaselineAlignmentLast:
return maxBaseline - baselineForItem(style, l);
case ASBaselineLayoutBaselineAlignmentNone:
return 0;
}
}
return 0;
}
static CGFloat maxDimensionForLayout(const ASLayout *l,
const ASStackLayoutSpecStyle &style)
{
CGFloat maxDimension = crossDimension(style.direction, l.size);
style.direction == ASStackLayoutDirectionVertical ? maxDimension += l.position.x : maxDimension += l.position.y;
return maxDimension;
}
ASBaselinePositionedLayout ASBaselinePositionedLayout::compute(const ASStackPositionedLayout &positionedLayout,
const ASBaselineLayoutSpecStyle &style,
const ASSizeRange &constrainedSize)
{
ASStackLayoutSpecStyle stackStyle = style.stackLayoutStyle;
/* Step 1: Look at each child and determine the distance from the top of the child node it's baseline.
For example, let's say we have the following two text nodes and want to align them to the first baseline:
Hello! Why, hello there! How
are you today?
The first node has a font of size 14, the second a font of size 12. The first node will have a baseline offset of
the ascender of a font of size 14, the second will have a baseline of the ascender of a font of size 12. The first
baseline will be larger so we will keep that as the max baseline.
However, if were to align from the last baseline we'd find the max baseline by taking the height of node and adding
the font's descender (its negative). In the case of the first node, which is only 1 line, this should be the same value as the ascender.
The second node, however, has a larger height and there will have a larger baseline offset.
*/
const auto baselineIt = std::max_element(positionedLayout.sublayouts.begin(), positionedLayout.sublayouts.end(), [&](const ASLayout *a, const ASLayout *b){
return baselineForItem(style, a) < baselineForItem(style, b);
});
const CGFloat maxBaseline = baselineIt == positionedLayout.sublayouts.end() ? 0 : baselineForItem(style, *baselineIt);
/*
Step 2: Find the max ascender for all of the children.
Imagine 3 nodes aligned horizontally, all with the same text but with font sizes of 12, 14, 16. Because it is has the largest
ascender node with font size of 16 will not need to move, the other two nodes will align to this node's baseline. The offset we will use
for each node is our computed maxAscender - node.ascender. If the 16pt node had an ascender of 10 and the 14pt node
had an ascender of 8, that means we will offset the 14pt node by 2 pts.
Note: if we are alinging to the last baseline, then we don't need this value in our computation. However, we do want
our layoutSpec to have it so that it can be baseline aligned with another text node or baseline layout spec.
*/
const auto ascenderIt = std::max_element(positionedLayout.sublayouts.begin(), positionedLayout.sublayouts.end(), [&](const ASLayout *a, const ASLayout *b){
return ((id<ASBaselineLayoutable>)a.layoutableObject).ascender < ((id<ASBaselineLayoutable>)b.layoutableObject).ascender;
});
const CGFloat maxAscender = baselineIt == positionedLayout.sublayouts.end() ? 0 : ((id<ASBaselineLayoutable>)(*ascenderIt).layoutableObject).ascender;
/*
Step 3: Take each child and update its layout position based on the baseline offset.
If this is a horizontal stack, we take a positioned child and add to its y offset to align it to the maxBaseline of the children.
If this is a vertical stack, we add the child's descender to the location of the next child to position. This will ensure the
spacing between the two nodes is from the baseline, not the bounding box.
*/
CGPoint p = CGPointZero;
BOOL first = YES;
auto stackedChildren = AS::map(positionedLayout.sublayouts, [&](ASLayout *l) -> ASLayout *{
__weak id<ASBaselineLayoutable> child = (id<ASBaselineLayoutable>) l.layoutableObject;
p = p + directionPoint(stackStyle.direction, child.spacingBefore, 0);
if (first) {
// if this is the first item use the previously computed start point
p = l.position;
} else {
// otherwise add the stack spacing
p = p + directionPoint(stackStyle.direction, stackStyle.spacing, 0);
}
first = NO;
// Find the difference between this node's baseline and the max baseline of all the children. Add this difference to the child's y position.
l.position = p + CGPointMake(0, baselineOffset(style, l, maxAscender, maxBaseline));
// If we are a vertical stack, add the item's descender (it is negative) to the offset for the next node. This will ensure we are spacing
// node from baselines and not bounding boxes.
CGFloat spacingAfterBaseline = 0;
if (stackStyle.direction == ASStackLayoutDirectionVertical) {
spacingAfterBaseline = child.descender;
}
p = p + directionPoint(stackStyle.direction, stackDimension(stackStyle.direction, l.size) + child.spacingAfter + spacingAfterBaseline, 0);
return l;
});
/*
Step 4: Since we have been mucking with positions, there is a chance that our cross size has changed. Imagine a node with a font size of 40
and another node with a font size of 12 but with multiple lines. We align these nodes to the first baseline, which will be the baseline of the node with
font size of 40 (max ascender). Now, we have to move the node with multiple lines down to the other node's baseline. This node with multiple lines will
extend below the first node farther than it did before aligning the baselines thus increasing the cross size.
After finding the new cross size, we need to clamp it so that it fits within the constrainted size.
*/
const auto it = std::max_element(stackedChildren.begin(), stackedChildren.end(),
[&](ASLayout *a, ASLayout *b) {
return maxDimensionForLayout(a, stackStyle) < maxDimensionForLayout(b, stackStyle);
});
const auto largestChildCrossSize = it == stackedChildren.end() ? 0 : maxDimensionForLayout(*it, stackStyle);
const auto minCrossSize = crossDimension(stackStyle.direction, constrainedSize.min);
const auto maxCrossSize = crossDimension(stackStyle.direction, constrainedSize.max);
const CGFloat crossSize = MIN(MAX(minCrossSize, largestChildCrossSize), maxCrossSize);
/*
Step 5: finally, we must find the smallest descender (descender is negative). This is since ASBaselineLayoutSpec implements
ASBaselineLayoutable and needs an ascender and descender to lay itself out properly.
*/
const auto descenderIt = std::max_element(stackedChildren.begin(), stackedChildren.end(), [&](const ASLayout *a, const ASLayout *b){
return a.position.y + a.size.height < b.position.y + b.size.height;
});
const CGFloat minDescender = descenderIt == stackedChildren.end() ? 0 : ((id<ASBaselineLayoutable>)(*descenderIt).layoutableObject).descender;
return {stackedChildren, crossSize, maxAscender, minDescender};
}

View File

@ -44,7 +44,7 @@ static ASStackPositionedLayout stackedLayout(const ASStackLayoutSpecStyle &style
const auto minCrossSize = crossDimension(style.direction, constrainedSize.min);
const auto maxCrossSize = crossDimension(style.direction, constrainedSize.max);
const CGFloat crossSize = MIN(MAX(minCrossSize, largestChildCrossSize), maxCrossSize);
CGPoint p = directionPoint(style.direction, offset, 0);
BOOL first = YES;
auto stackedChildren = AS::map(unpositionedLayout.items, [&](const ASStackUnpositionedItem &l) -> ASLayout *{
@ -54,6 +54,7 @@ static ASStackPositionedLayout stackedLayout(const ASStackLayoutSpecStyle &style
}
first = NO;
l.layout.position = p + directionPoint(style.direction, 0, crossOffset(style, l, crossSize));
p = p + directionPoint(style.direction, stackDimension(style.direction, l.layout.size) + l.child.spacingAfter, 0);
return l.layout;
});

View File

@ -16,7 +16,7 @@
struct ASStackUnpositionedItem {
/** The original source child. */
id<ASLayoutable> child;
id<ASStackLayoutable> child;
/** The proposed layout. */
ASLayout *layout;
};
@ -31,7 +31,7 @@ struct ASStackUnpositionedLayout {
const CGFloat violation;
/** Given a set of children, computes the unpositioned layouts for those children. */
static ASStackUnpositionedLayout compute(const std::vector<id<ASLayoutable>> &children,
static ASStackUnpositionedLayout compute(const std::vector<id<ASStackLayoutable>> &children,
const ASStackLayoutSpecStyle &style,
const ASSizeRange &sizeRange);
};

View File

@ -18,7 +18,7 @@
/**
Sizes the child given the parameters specified, and returns the computed layout.
*/
static ASLayout *crossChildLayout(const id<ASLayoutable> child,
static ASLayout *crossChildLayout(const id<ASStackLayoutable> child,
const ASStackLayoutSpecStyle style,
const CGFloat stackMin,
const CGFloat stackMax,
@ -186,7 +186,7 @@ static std::function<BOOL(const ASStackUnpositionedItem &)> isFlexibleInViolatio
}
}
ASDISPLAYNODE_INLINE BOOL isFlexibleInBothDirections(id<ASLayoutable> child)
ASDISPLAYNODE_INLINE BOOL isFlexibleInBothDirections(id<ASStackLayoutable> child)
{
return child.flexGrow && child.flexShrink;
}
@ -195,7 +195,7 @@ ASDISPLAYNODE_INLINE BOOL isFlexibleInBothDirections(id<ASLayoutable> child)
If we have a single flexible (both shrinkable and growable) child, and our allowed size range is set to a specific
number then we may avoid the first "intrinsic" size calculation.
*/
ASDISPLAYNODE_INLINE BOOL useOptimizedFlexing(const std::vector<id<ASLayoutable>> &children,
ASDISPLAYNODE_INLINE BOOL useOptimizedFlexing(const std::vector<id<ASStackLayoutable>> &children,
const ASStackLayoutSpecStyle &style,
const ASSizeRange &sizeRange)
{
@ -283,7 +283,7 @@ static void flexChildrenAlongStackDimension(std::vector<ASStackUnpositionedItem>
Performs the first unconstrained layout of the children, generating the unpositioned items that are then flexed and
stretched.
*/
static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStackDimension(const std::vector<id<ASLayoutable>> &children,
static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStackDimension(const std::vector<id<ASStackLayoutable>> &children,
const ASStackLayoutSpecStyle &style,
const ASSizeRange &sizeRange,
const CGSize size,
@ -292,7 +292,7 @@ static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStac
const CGFloat minCrossDimension = crossDimension(style.direction, sizeRange.min);
const CGFloat maxCrossDimension = crossDimension(style.direction, sizeRange.max);
return AS::map(children, [&](id<ASLayoutable> child) -> ASStackUnpositionedItem {
return AS::map(children, [&](id<ASStackLayoutable> child) -> ASStackUnpositionedItem {
const BOOL isUnconstrainedFlexBasis = ASRelativeDimensionEqualToRelativeDimension(ASRelativeDimensionUnconstrained, child.flexBasis);
const CGFloat exactStackDimension = ASRelativeDimensionResolve(child.flexBasis, stackDimension(style.direction, size));
@ -312,7 +312,7 @@ static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStac
});
}
ASStackUnpositionedLayout ASStackUnpositionedLayout::compute(const std::vector<id<ASLayoutable>> &children,
ASStackUnpositionedLayout ASStackUnpositionedLayout::compute(const std::vector<id<ASStackLayoutable>> &children,
const ASStackLayoutSpecStyle &style,
const ASSizeRange &sizeRange)
{

View File

@ -58,9 +58,7 @@
1A943BF0259746F18D6E423F /* Frameworks */,
1AE410B73DA5C3BD087ACDD7 /* Pods */,
);
indentWidth = 2;
sourceTree = "<group>";
tabWidth = 2;
};
05E2128219D4DB510098F589 /* Products */ = {
isa = PBXGroup;