Introduce ASLayoutable and eliminate ASCompositeNode:

- Both ASDisplayNode and ASLayoutNode conforms to this protocol.
- ASDisplayNode can be embeded directly into layout graph.
- Eliminate ASCompositeNode.
- Fix ASStaticSizeDisplayNode not recpect min constrained size.
- Updated tests.
This commit is contained in:
Huy Nguyen 2015-06-26 08:41:51 +07:00
parent 697b9f4c3c
commit f588bceb4d
40 changed files with 262 additions and 363 deletions

View File

@ -193,8 +193,6 @@
ACF6ED1B1B17843500DA7C62 /* ASBackgroundLayoutNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutNode.mm */; };
ACF6ED1C1B17843500DA7C62 /* ASCenterLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED031B17843500DA7C62 /* ASCenterLayoutNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
ACF6ED1D1B17843500DA7C62 /* ASCenterLayoutNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED041B17843500DA7C62 /* ASCenterLayoutNode.mm */; };
ACF6ED1E1B17843500DA7C62 /* ASCompositeNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED051B17843500DA7C62 /* ASCompositeNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
ACF6ED1F1B17843500DA7C62 /* ASCompositeNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED061B17843500DA7C62 /* ASCompositeNode.mm */; };
ACF6ED201B17843500DA7C62 /* ASDimension.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED071B17843500DA7C62 /* ASDimension.h */; settings = {ATTRIBUTES = (Public, ); }; };
ACF6ED211B17843500DA7C62 /* ASDimension.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED081B17843500DA7C62 /* ASDimension.mm */; };
ACF6ED221B17843500DA7C62 /* ASInsetLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED091B17843500DA7C62 /* ASInsetLayoutNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -203,7 +201,7 @@
ACF6ED251B17843500DA7C62 /* ASLayout.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */; };
ACF6ED261B17843500DA7C62 /* ASLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED0D1B17843500DA7C62 /* ASLayoutNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
ACF6ED271B17843500DA7C62 /* ASLayoutNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED0E1B17843500DA7C62 /* ASLayoutNode.mm */; };
ACF6ED2A1B17843500DA7C62 /* ASLayoutNodeSubclass.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED111B17843500DA7C62 /* ASLayoutNodeSubclass.h */; settings = {ATTRIBUTES = (Public, ); }; };
ACF6ED2A1B17843500DA7C62 /* ASLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED111B17843500DA7C62 /* ASLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
ACF6ED2B1B17843500DA7C62 /* ASOverlayLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED121B17843500DA7C62 /* ASOverlayLayoutNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
ACF6ED2C1B17843500DA7C62 /* ASOverlayLayoutNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = ACF6ED131B17843500DA7C62 /* ASOverlayLayoutNode.mm */; };
ACF6ED2D1B17843500DA7C62 /* ASRatioLayoutNode.h in Headers */ = {isa = PBXBuildFile; fileRef = ACF6ED141B17843500DA7C62 /* ASRatioLayoutNode.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -416,7 +414,7 @@
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>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
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>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
058D09E2195D050800B7D73C /* _ASDisplayLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = _ASDisplayLayer.h; sourceTree = "<group>"; };
@ -529,8 +527,6 @@
ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = ASBackgroundLayoutNode.mm; path = AsyncDisplayKit/Layout/ASBackgroundLayoutNode.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
ACF6ED031B17843500DA7C62 /* ASCenterLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASCenterLayoutNode.h; path = AsyncDisplayKit/Layout/ASCenterLayoutNode.h; sourceTree = "<group>"; };
ACF6ED041B17843500DA7C62 /* ASCenterLayoutNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = ASCenterLayoutNode.mm; path = AsyncDisplayKit/Layout/ASCenterLayoutNode.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
ACF6ED051B17843500DA7C62 /* ASCompositeNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASCompositeNode.h; path = AsyncDisplayKit/Layout/ASCompositeNode.h; sourceTree = "<group>"; };
ACF6ED061B17843500DA7C62 /* ASCompositeNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASCompositeNode.mm; path = AsyncDisplayKit/Layout/ASCompositeNode.mm; sourceTree = "<group>"; };
ACF6ED071B17843500DA7C62 /* ASDimension.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASDimension.h; path = AsyncDisplayKit/Layout/ASDimension.h; sourceTree = "<group>"; };
ACF6ED081B17843500DA7C62 /* ASDimension.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASDimension.mm; path = AsyncDisplayKit/Layout/ASDimension.mm; sourceTree = "<group>"; };
ACF6ED091B17843500DA7C62 /* ASInsetLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASInsetLayoutNode.h; path = AsyncDisplayKit/Layout/ASInsetLayoutNode.h; sourceTree = "<group>"; };
@ -539,7 +535,7 @@
ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayout.mm; path = AsyncDisplayKit/Layout/ASLayout.mm; sourceTree = "<group>"; };
ACF6ED0D1B17843500DA7C62 /* ASLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutNode.h; path = AsyncDisplayKit/Layout/ASLayoutNode.h; sourceTree = "<group>"; };
ACF6ED0E1B17843500DA7C62 /* ASLayoutNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = ASLayoutNode.mm; path = AsyncDisplayKit/Layout/ASLayoutNode.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
ACF6ED111B17843500DA7C62 /* ASLayoutNodeSubclass.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutNodeSubclass.h; path = AsyncDisplayKit/Layout/ASLayoutNodeSubclass.h; sourceTree = "<group>"; };
ACF6ED111B17843500DA7C62 /* ASLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutable.h; path = AsyncDisplayKit/Layout/ASLayoutable.h; sourceTree = "<group>"; };
ACF6ED121B17843500DA7C62 /* ASOverlayLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASOverlayLayoutNode.h; path = AsyncDisplayKit/Layout/ASOverlayLayoutNode.h; sourceTree = "<group>"; };
ACF6ED131B17843500DA7C62 /* ASOverlayLayoutNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; name = ASOverlayLayoutNode.mm; path = AsyncDisplayKit/Layout/ASOverlayLayoutNode.mm; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
ACF6ED141B17843500DA7C62 /* ASRatioLayoutNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASRatioLayoutNode.h; path = AsyncDisplayKit/Layout/ASRatioLayoutNode.h; sourceTree = "<group>"; };
@ -903,17 +899,15 @@
ACF6ED021B17843500DA7C62 /* ASBackgroundLayoutNode.mm */,
ACF6ED031B17843500DA7C62 /* ASCenterLayoutNode.h */,
ACF6ED041B17843500DA7C62 /* ASCenterLayoutNode.mm */,
ACF6ED051B17843500DA7C62 /* ASCompositeNode.h */,
ACF6ED061B17843500DA7C62 /* ASCompositeNode.mm */,
ACF6ED071B17843500DA7C62 /* ASDimension.h */,
ACF6ED081B17843500DA7C62 /* ASDimension.mm */,
ACF6ED091B17843500DA7C62 /* ASInsetLayoutNode.h */,
ACF6ED0A1B17843500DA7C62 /* ASInsetLayoutNode.mm */,
ACF6ED0B1B17843500DA7C62 /* ASLayout.h */,
ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */,
ACF6ED111B17843500DA7C62 /* ASLayoutable.h */,
ACF6ED0D1B17843500DA7C62 /* ASLayoutNode.h */,
ACF6ED0E1B17843500DA7C62 /* ASLayoutNode.mm */,
ACF6ED111B17843500DA7C62 /* ASLayoutNodeSubclass.h */,
ACF6ED121B17843500DA7C62 /* ASOverlayLayoutNode.h */,
ACF6ED131B17843500DA7C62 /* ASOverlayLayoutNode.mm */,
ACF6ED141B17843500DA7C62 /* ASRatioLayoutNode.h */,
@ -971,10 +965,9 @@
ACF6ED201B17843500DA7C62 /* ASDimension.h in Headers */,
ACF6ED2B1B17843500DA7C62 /* ASOverlayLayoutNode.h in Headers */,
ACF6ED1C1B17843500DA7C62 /* ASCenterLayoutNode.h in Headers */,
ACF6ED2A1B17843500DA7C62 /* ASLayoutNodeSubclass.h in Headers */,
ACF6ED2A1B17843500DA7C62 /* ASLayoutable.h in Headers */,
ACF6ED311B17843500DA7C62 /* ASStaticLayoutNode.h in Headers */,
ACF6ED241B17843500DA7C62 /* ASLayout.h in Headers */,
ACF6ED1E1B17843500DA7C62 /* ASCompositeNode.h in Headers */,
ACF6ED2F1B17843500DA7C62 /* ASStackLayoutNode.h in Headers */,
ACF6ED1A1B17843500DA7C62 /* ASBackgroundLayoutNode.h in Headers */,
291B63FB1AA53A7A000A71B3 /* ASScrollDirection.h in Headers */,
@ -1391,7 +1384,6 @@
058D0A1C195D050800B7D73C /* ASTextNodeCoreTextAdditions.m in Sources */,
058D0A13195D050800B7D73C /* ASControlNode.m in Sources */,
ACF6ED4C1B17847A00DA7C62 /* ASInternalHelpers.mm in Sources */,
ACF6ED1F1B17843500DA7C62 /* ASCompositeNode.mm in Sources */,
058D0A19195D050800B7D73C /* _ASDisplayView.mm in Sources */,
205F0E101B371875007741D0 /* UICollectionViewLayout+ASConvenience.m in Sources */,
05A6D05B19D0EB64002DD95E /* ASDealloc2MainObject.m in Sources */,

View File

@ -13,7 +13,6 @@
#import <AsyncDisplayKit/ASTextNode.h>
#import "ASInsetLayoutNode.h"
#import "ASCompositeNode.h"
#pragma mark -
#pragma mark ASCellNode
@ -106,12 +105,12 @@ static const CGFloat kFontSize = 18.0f;
return self;
}
- (ASLayoutNode *)layoutNodeThatFits:(CGSize)constrainedSize
{
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize{
static const CGFloat kHorizontalPadding = 15.0f;
static const CGFloat kVerticalPadding = 11.0f;
UIEdgeInsets insets = UIEdgeInsetsMake(kVerticalPadding, kHorizontalPadding, kVerticalPadding, kHorizontalPadding);
return [ASInsetLayoutNode newWithInsets:insets node:[ASCompositeNode newWithDisplayNode:_textNode]];
id<ASLayoutable> layout = [ASInsetLayoutNode newWithInsets:insets child:_textNode];
return [layout calculateLayoutThatFits:constrainedSize];
}
- (void)setText:(NSString *)text

View File

@ -14,7 +14,6 @@
#import <AsyncDisplayKit/ASThread.h>
#import <AsyncDisplayKit/ASLayout.h>
@class ASLayoutNode;
/**
* The subclass header _ASDisplayNode+Subclasses_ defines the following methods that either must or can be overriden by
@ -108,22 +107,6 @@
*/
- (void)layoutDidFinish;
- (ASLayoutNode *)layoutNodeThatFits:(CGSize)constrainedSize;
/**
* @abstract Return the calculated layout.
*
* @param constrainedSize The maximum size the receiver should fit in.
*
* @discussion Subclasses that override should expect this method to be called on a non-main thread. The returned layout
* is cached by ASDisplayNode for quick access during -layout, via -calculatedSize. Other expensive work that needs to
* be done before display can be performed here, and using ivars to cache any valuable intermediate results is
* encouraged.
*
* @note This method should not be called directly outside of ASDisplayNode; use -measure: or -calculatedLayout instead.
*/
- (ASLayout *)calculateLayoutThatFits:(CGSize)constrainedSize;
/**
* @abstract Invalidate previously measured and cached layout.
*

View File

@ -11,6 +11,7 @@
#import <AsyncDisplayKit/_ASAsyncTransactionContainer.h>
#import <AsyncDisplayKit/ASBaseDefines.h>
#import <AsyncDisplayKit/ASDealloc2MainObject.h>
#import <AsyncDisplayKit/ASLayoutable.h>
typedef UIView *(^ASDisplayNodeViewBlock)();
@ -32,7 +33,7 @@ typedef CALayer *(^ASDisplayNodeLayerBlock)();
*
*/
@interface ASDisplayNode : ASDealloc2MainObject
@interface ASDisplayNode : ASDealloc2MainObject <ASLayoutable>
/** @name Initializing a node object */
@ -128,10 +129,10 @@ typedef CALayer *(^ASDisplayNodeLayerBlock)();
* @discussion Though this method does not set the bounds of the view, it does have side effects--caching both the
* constraint and the result.
*
* @warning Subclasses must not override this; it caches results from -layoutNodeThatFits:. Calling this method may
* @warning Subclasses must not override this; it caches results from -calculateLayoutThatFits:. Calling this method may
* be expensive if result is not cached.
*
* @see [ASDisplayNode(Subclassing) layoutNodeThatFits:]
* @see [ASDisplayNode(Subclassing) calculateLayoutThatFits:]
*/
- (CGSize)measure:(CGSize)constrainedSize;
@ -150,10 +151,25 @@ typedef CALayer *(^ASDisplayNodeLayerBlock)();
/**
* @abstract Return the constrained size used for calculating layout.
*
* @return The constrained size used by layoutNodeThatFits:.
* @return The maximum constrained size used by calculateLayoutThatFits:.
*/
@property (nonatomic, readonly, assign) CGSize constrainedSizeForCalculatedLayout;
/**
* @abstract Calculate a layout based on given size range.
*
* @param constrainedSize The minimum and maximum sizes the receiver should fit in.
*
* @return An ASLayout instance defining the layout of the receiver and its children.
*
* @discussion Subclasses that override should expect this method to be called on a non-main thread. The returned layout
* is cached by ASDisplayNode for quick access during -layout, via -calculatedSize. Other expensive work that needs to
* be done before display can be performed here, and using ivars to cache any valuable intermediate results is
* encouraged.
*
* @note This method should not be called directly outside of ASDisplayNode; use -measure: or -calculatedLayout instead.
*/
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize;
/** @name Managing the nodes hierarchy */

View File

@ -20,8 +20,6 @@
#import "ASDisplayNodeExtras.h"
#import "ASInternalHelpers.h"
#import "ASLayoutNodeSubclass.h"
#import "ASCompositeNode.h"
#import "ASLayoutNodeUtilities.h"
@interface ASDisplayNode () <UIGestureRecognizerDelegate>
@ -432,7 +430,7 @@ void ASDisplayNodePerformBlockOnMainThread(void (^block)())
// - the width is different from the last time
// - the height is different from the last time
if (!_flags.isMeasured || !CGSizeEqualToSize(constrainedSize, _constrainedSize)) {
_layout = [self calculateLayoutThatFits:constrainedSize];
_layout = [self calculateLayoutThatFits:ASSizeRangeMake(CGSizeZero, constrainedSize)];
_constrainedSize = constrainedSize;
_flags.isMeasured = YES;
}
@ -1261,18 +1259,10 @@ static NSInteger incrementIfFound(NSInteger i) {
#pragma mark - For Subclasses
- (ASLayoutNode *)layoutNodeThatFits:(CGSize)constrainedSize
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
ASDisplayNodeAssertThreadAffinity(self);
return [ASLayoutNode new];
}
- (ASLayout *)calculateLayoutThatFits:(CGSize)constrainedSize
{
ASDisplayNodeAssertThreadAffinity(self);
ASLayoutNode *layoutNode = [self layoutNodeThatFits:constrainedSize];
ASLayout *layout = [layoutNode calculateLayoutThatFits:{CGSizeZero, constrainedSize}];
return layout;
return [ASLayout newWithLayoutableObject:self size:constrainedSize.min];
}
- (ASLayout *)calculatedLayout
@ -1389,16 +1379,15 @@ static NSInteger incrementIfFound(NSInteger i) {
if (context.visited) {
stack.pop();
} else {
ASDisplayNodeAssertNotNil(context.layout.node, "node is required in calculated ASLayout.");
ASDisplayNodeAssertNotNil(context.layout.layoutableObject, "layoutableObject is required in calculated ASLayout.");
context.visited = YES;
if ([context.layout.node isKindOfClass:[ASCompositeNode class]]) {
ASDisplayNode *subnode = ((ASCompositeNode *)context.layout.node).displayNode;
ASDisplayNodeAssertNotNil(subnode, "displayNode is required in ASCompositeNode.");
id<ASLayoutable> layoutableObject = context.layout.layoutableObject;
if ([layoutableObject isKindOfClass:[ASDisplayNode class]] && layoutableObject != self) {
CGPoint subnodePosition = context.absolutePosition;
CGSize subnodeSize = context.layout.size;
subnode.frame = CGRectMake(subnodePosition.x, subnodePosition.y, subnodeSize.width, subnodeSize.height);
((ASDisplayNode *)layoutableObject).frame = CGRectMake(subnodePosition.x, subnodePosition.y,
subnodeSize.width, subnodeSize.height);
}
for (ASLayoutChild *child in context.layout.children) {

View File

@ -145,12 +145,12 @@
[self.view addSubview:_textKitComponents.textView];
}
- (ASLayout *)calculateLayoutThatFits:(CGSize)constrainedSize
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
ASTextKitComponents *displayedComponents = [self isDisplayingPlaceholder] ? _placeholderTextKitComponents : _textKitComponents;
CGSize textSize = [displayedComponents sizeForConstrainedWidth:constrainedSize.width];
CGSize finalSize = CGSizeMake(constrainedSize.width, fminf(textSize.height, constrainedSize.height));
return [ASLayout newWithNode:[ASLayoutNode new] size:finalSize];
CGSize textSize = [displayedComponents sizeForConstrainedWidth:constrainedSize.max.width];
CGSize finalSize = CGSizeMake(constrainedSize.max.width, fminf(textSize.height, constrainedSize.max.height));
return [ASLayout newWithLayoutableObject:self size:finalSize];
}
- (void)layout

View File

@ -18,7 +18,6 @@
#import "ASImageNode+CGExtras.h"
#import "ASInternalHelpers.h"
#import "ASLayoutNode.h"
@interface _ASImageNodeDrawParameters : NSObject
@ -109,13 +108,13 @@
return nil;
}
- (ASLayout *)calculateLayoutThatFits:(CGSize)constrainedSize
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
ASDN::MutexLocker l(_imageLock);
CGSize size = CGSizeZero;
if (_image)
size = _image.size;
return [ASLayout newWithNode:[ASLayoutNode new] size:size];
return [ASLayout newWithLayoutableObject:self size:ASSizeRangeClamp(constrainedSize, size)];
}
- (void)setImage:(UIImage *)image

View File

@ -186,10 +186,10 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
#pragma mark - ASDisplayNode
- (ASLayout *)calculateLayoutThatFits:(CGSize)constrainedSize
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
ASDisplayNodeAssert(constrainedSize.width >= 0, @"Constrained width for text (%f) is too narrow", constrainedSize.width);
ASDisplayNodeAssert(constrainedSize.height >= 0, @"Constrained height for text (%f) is too short", constrainedSize.height);
ASDisplayNodeAssert(constrainedSize.max.width >= 0, @"Constrained width for text (%f) is too narrow", constrainedSize.max.width);
ASDisplayNodeAssert(constrainedSize.max.height >= 0, @"Constrained height for text (%f) is too short", constrainedSize.max.height);
// The supplied constrainedSize should include room for shadowPadding.
// Inset the constrainedSize by the shadow padding to get the size available for text.
UIEdgeInsets shadowPadding = [[self _shadower] shadowPadding];
@ -197,7 +197,7 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
UIEdgeInsets shadowPaddingOutset = ASDNEdgeInsetsInvert(shadowPadding);
// Inset the padded constrainedSize to get the remaining size available for text
CGRect constrainedRect = CGRect{CGPointZero, constrainedSize};
CGRect constrainedRect = CGRect{CGPointZero, constrainedSize.max};
CGSize constrainedSizeForText = UIEdgeInsetsInsetRect(constrainedRect, shadowPaddingOutset).size;
ASDisplayNodeAssert(constrainedSizeForText.width >= 0, @"Constrained width for text (%f) after subtracting shadow padding (%@) is too narrow", constrainedSizeForText.width, NSStringFromUIEdgeInsets(shadowPadding));
ASDisplayNodeAssert(constrainedSizeForText.height >= 0, @"Constrained height for text (%f) after subtracting shadow padding (%@) is too short", constrainedSizeForText.height, NSStringFromUIEdgeInsets(shadowPadding));
@ -212,9 +212,9 @@ ASDISPLAYNODE_INLINE CGFloat ceilPixelValue(CGFloat f)
ASDisplayNodeAssert(renderSizePlusShadowPadding.width >= 0, @"Calculated width for text with shadow padding (%f) is too narrow", constrainedSizeForText.width);
ASDisplayNodeAssert(renderSizePlusShadowPadding.height >= 0, @"Calculated height for text with shadow padding (%f) is too short", constrainedSizeForText.height);
CGSize finalSize = CGSizeMake(MIN(ceilPixelValue(renderSizePlusShadowPadding.width), constrainedSize.width),
MIN(ceilPixelValue(renderSizePlusShadowPadding.height), constrainedSize.height));
return [ASLayout newWithNode:[ASLayoutNode new] size:finalSize];
CGSize finalSize = CGSizeMake(MIN(ceilPixelValue(renderSizePlusShadowPadding.width), constrainedSize.max.width),
MIN(ceilPixelValue(renderSizePlusShadowPadding.height), constrainedSize.max.height));
return [ASLayout newWithLayoutableObject:self size:finalSize];
}
- (void)displayDidFinish

View File

@ -27,7 +27,7 @@
#import <AsyncDisplayKit/ASLayout.h>
#import <AsyncDisplayKit/ASDimension.h>
#import <AsyncDisplayKit/ASCompositeNode.h>
#import <AsyncDisplayKit/ASLayoutable.h>
#import <AsyncDisplayKit/ASLayoutNode.h>
#import <AsyncDisplayKit/ASBackgroundLayoutNode.h>
#import <AsyncDisplayKit/ASCenterLayoutNode.h>

View File

@ -16,10 +16,10 @@
@interface ASBackgroundLayoutNode : ASLayoutNode
/**
@param node A child that is laid out to determine the size of this node. If this is nil, then this method
@param child A child that is laid out to determine the size of this node. If this is nil, then this method
returns nil.
@param background A child that is laid out behind it. May be nil, in which case the background is omitted.
@param background A layoutable object that is laid out behind the child. May be nil, in which case the background is omitted.
*/
+ (instancetype)newWithNode:(ASLayoutNode *)node background:(ASLayoutNode *)background;
+ (instancetype)newWithChild:(id<ASLayoutable>)child background:(id<ASLayoutable>)background;
@end

View File

@ -13,24 +13,22 @@
#import "ASAssert.h"
#import "ASBaseDefines.h"
#import "ASLayoutNodeSubclass.h"
@interface ASBackgroundLayoutNode ()
{
ASLayoutNode *_node;
ASLayoutNode *_background;
id<ASLayoutable> _child;
id<ASLayoutable> _background;
}
@end
@implementation ASBackgroundLayoutNode
+ (instancetype)newWithNode:(ASLayoutNode *)node background:(ASLayoutNode *)background
+ (instancetype)newWithChild:(id<ASLayoutable>)child background:(id<ASLayoutable>)background
{
if (node == nil) {
if (child == nil) {
return nil;
}
ASBackgroundLayoutNode *n = [super new];
n->_node = node;
n->_child = child;
n->_background = background;
return n;
}
@ -45,7 +43,7 @@
*/
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
ASLayout *contentsLayout = [_node calculateLayoutThatFits:constrainedSize];
ASLayout *contentsLayout = [_child calculateLayoutThatFits:constrainedSize];
NSMutableArray *children = [NSMutableArray arrayWithCapacity:2];
if (_background) {
@ -55,7 +53,7 @@
}
[children addObject:[ASLayoutChild newWithPosition:{0,0} layout:contentsLayout]];
return [ASLayout newWithNode:self size:contentsLayout.size children:children];
return [ASLayout newWithLayoutableObject:self size:contentsLayout.size children:children];
}
@end

View File

@ -41,6 +41,6 @@ typedef NS_OPTIONS(NSUInteger, ASCenterLayoutNodeSizingOptions) {
*/
+ (instancetype)newWithCenteringOptions:(ASCenterLayoutNodeCenteringOptions)centeringOptions
sizingOptions:(ASCenterLayoutNodeSizingOptions)sizingOptions
child:(ASLayoutNode *)child;
child:(id<ASLayoutable>)child;
@end

View File

@ -11,18 +11,17 @@
#import "ASCenterLayoutNode.h"
#import "ASInternalHelpers.h"
#import "ASLayoutNodeSubclass.h"
@implementation ASCenterLayoutNode
{
ASCenterLayoutNodeCenteringOptions _centeringOptions;
ASCenterLayoutNodeSizingOptions _sizingOptions;
ASLayoutNode *_child;
id<ASLayoutable> _child;
}
+ (instancetype)newWithCenteringOptions:(ASCenterLayoutNodeCenteringOptions)centeringOptions
sizingOptions:(ASCenterLayoutNodeSizingOptions)sizingOptions
child:(ASLayoutNode *)child
child:(id<ASLayoutable>)child
{
ASCenterLayoutNode *n = [super new];
if (n) {
@ -73,9 +72,9 @@
ASRoundPixelValue(shouldCenterAlongY ? (size.height - childLayout.size.height) * 0.5f : 0)
};
return [ASLayout newWithNode:self
size:size
children:@[[ASLayoutChild newWithPosition:childPosition layout:childLayout]]];
return [ASLayout newWithLayoutableObject:self
size:size
children:@[[ASLayoutChild newWithPosition:childPosition layout:childLayout]]];
}
@end

View File

@ -1,21 +0,0 @@
/*
* Copyright (c) 2015-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/ASLayoutNode.h>
@class ASDisplayNode;
@interface ASCompositeNode : ASLayoutNode
@property (nonatomic, readonly) ASDisplayNode *displayNode;
+ (instancetype)newWithDisplayNode:(ASDisplayNode *)displayNode;
@end

View File

@ -1,43 +0,0 @@
/*
* Copyright (c) 2015-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 "ASCompositeNode.h"
#import "ASBaseDefines.h"
#import "ASDisplayNode.h"
#import "ASLayoutNodeSubclass.h"
@implementation ASCompositeNode
+ (instancetype)newWithDisplayNode:(ASDisplayNode *)displayNode
{
if (displayNode == nil) {
return nil;
}
ASCompositeNode *n = [super new];
if (n) {
n->_displayNode = displayNode;
}
return n;
}
+ (instancetype)new
{
ASDISPLAYNODE_NOT_DESIGNATED_INITIALIZER();
}
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
CGSize measuredSize = ASSizeRangeClamp(constrainedSize, [_displayNode measure:constrainedSize.max]);
return [ASLayout newWithNode:self size:measuredSize];
}
@end

View File

@ -31,8 +31,8 @@
/**
@param insets The amount of space to inset on each side.
@param node The wrapped child layout node to inset. If nil, this method returns nil.
@param child The wrapped child to inset. If nil, this method returns nil.
*/
+ (instancetype)newWithInsets:(UIEdgeInsets)insets node:(ASLayoutNode *)node;
+ (instancetype)newWithInsets:(UIEdgeInsets)insets child:(id<ASLayoutable>)child;
@end

View File

@ -14,12 +14,11 @@
#import "ASBaseDefines.h"
#import "ASInternalHelpers.h"
#import "ASLayoutNodeSubclass.h"
@interface ASInsetLayoutNode ()
{
UIEdgeInsets _insets;
ASLayoutNode *_node;
id<ASLayoutable> _child;
}
@end
@ -43,15 +42,15 @@ static CGFloat centerInset(CGFloat outer, CGFloat inner)
@implementation ASInsetLayoutNode
+ (instancetype)newWithInsets:(UIEdgeInsets)insets node:(ASLayoutNode *)node
+ (instancetype)newWithInsets:(UIEdgeInsets)insets child:(id<ASLayoutable>)child
{
if (node == nil) {
if (child == nil) {
return nil;
}
ASInsetLayoutNode *n = [super new];
if (n) {
n->_insets = insets;
n->_node = node;
n->_child = child;
}
return n;
}
@ -85,7 +84,7 @@ static CGFloat centerInset(CGFloat outer, CGFloat inner)
MAX(0, constrainedSize.max.height - insetsY),
}
};
ASLayout *childLayout = [_node calculateLayoutThatFits:insetConstrainedSize];
ASLayout *childLayout = [_child calculateLayoutThatFits:insetConstrainedSize];
const CGSize computedSize = ASSizeRangeClamp(constrainedSize, {
finite(childLayout.size.width + _insets.left + _insets.right, constrainedSize.max.width),
@ -100,9 +99,9 @@ static CGFloat centerInset(CGFloat outer, CGFloat inner)
constrainedSize.max.height -
(finite(_insets.bottom,
centerInset(constrainedSize.max.height, childLayout.size.height)) + childLayout.size.height));
return [ASLayout newWithNode:self
size:computedSize
children:@[[ASLayoutChild newWithPosition:{x,y} layout:childLayout]]];
return [ASLayout newWithLayoutableObject:self
size:computedSize
children:@[[ASLayoutChild newWithPosition:{x,y} layout:childLayout]]];
}
@end

View File

@ -10,25 +10,26 @@
#import <UIKit/UIKit.h>
#import <AsyncDisplayKit/ASAssert.h>
@class ASLayoutNode;
#import <AsyncDisplayKit/ASLayoutable.h>
/** Represents the computed size of a layout node, as well as the computed sizes and positions of its children. */
@interface ASLayout : NSObject
@property (nonatomic, readonly) ASLayoutNode *node;
@property (nonatomic, readonly) id<ASLayoutable> layoutableObject;
@property (nonatomic, readonly) CGSize size;
/**
* Each item is of type ASLayoutChild.
*/
@property (nonatomic, readonly) NSArray *children;
+ (instancetype)newWithNode:(ASLayoutNode *)node size:(CGSize)size children:(NSArray *)children;
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject
size:(CGSize)size
children:(NSArray *)children;
/**
* Convenience that does not have any children.
*/
+ (instancetype)newWithNode:(ASLayoutNode *)node size:(CGSize)size;
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject size:(CGSize)size;
@end

View File

@ -12,20 +12,22 @@
@implementation ASLayout
+ (instancetype)newWithNode:(ASLayoutNode *)node size:(CGSize)size children:(NSArray *)children
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject
size:(CGSize)size
children:(NSArray *)children
{
ASLayout *l = [super new];
if (l) {
l->_node = node;
l->_layoutableObject = layoutableObject;
l->_size = size;
l->_children = [children copy];
}
return l;
}
+ (instancetype)newWithNode:(ASLayoutNode *)node size:(CGSize)size
+ (instancetype)newWithLayoutableObject:(id<ASLayoutable>)layoutableObject size:(CGSize)size
{
return [self newWithNode:node size:size children:nil];
return [self newWithLayoutableObject:layoutableObject size:size children:nil];
}
@end

View File

@ -8,9 +8,10 @@
*
*/
#import <AsyncDisplayKit/ASDimension.h>
#import <AsyncDisplayKit/ASLayoutable.h>
#import <AsyncDisplayKit/ASLayout.h>
/** A layout node is an immutable object that describes a layout, loosely inspired by React. */
@interface ASLayoutNode : NSObject
@interface ASLayoutNode : NSObject <ASLayoutable>
@end

View File

@ -9,7 +9,6 @@
*/
#import "ASLayoutNode.h"
#import "ASLayoutNodeSubclass.h"
#import "ASAssert.h"
#import "ASBaseDefines.h"
@ -23,7 +22,7 @@
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
return [ASLayout newWithNode:self size:constrainedSize.min];
return [ASLayout newWithLayoutableObject:self size:constrainedSize.min];
}
@end

View File

@ -1,25 +0,0 @@
/*
* 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/ASLayoutNode.h>
#import <AsyncDisplayKit/ASLayout.h>
@interface ASLayoutNode ()
/**
Override this method to calculate your node's layout.
@param constrainedSize The maximum size the receiver should fit in.
@return An ASLayout instance defining the layout of the receiver and its children.
*/
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize;
@end

View File

@ -0,0 +1,30 @@
/*
* 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/ASDimension.h>
@class ASLayout;
@protocol ASLayoutable <NSObject>
/**
* @abstract Calculate a layout based on given size range.
*
* @param constrainedSize The minimum and maximum sizes the receiver should fit in.
*
* @return An ASLayout instance defining the layout of the receiver and its children.
*
* @discussion This method is called on a non-main thread. Other expensive work that needs to
* be done before display can be performed here, and using ivars to cache any valuable intermediate results is
* encouraged.
*/
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize;
@end

View File

@ -11,10 +11,10 @@
#import <AsyncDisplayKit/ASLayoutNode.h>
/**
This node lays out a single node and then overlays a node on top of it streched to its size
This node lays out a single layoutable child and then overlays a layoutable object on top of it streched to its size
*/
@interface ASOverlayLayoutNode : ASLayoutNode
+ (instancetype)newWithNode:(ASLayoutNode *)node overlay:(ASLayoutNode *)overlay;
+ (instancetype)newWithChild:(id<ASLayoutable>)child overlay:(id<ASLayoutable>)overlay;
@end

View File

@ -13,21 +13,19 @@
#import "ASAssert.h"
#import "ASBaseDefines.h"
#import "ASLayoutNodeSubclass.h"
@implementation ASOverlayLayoutNode
{
ASLayoutNode *_overlay;
ASLayoutNode *_node;
id<ASLayoutable> _overlay;
id<ASLayoutable> _child;
}
+ (instancetype)newWithNode:(ASLayoutNode *)node overlay:(ASLayoutNode *)overlay
+ (instancetype)newWithChild:(id<ASLayoutable>)child overlay:(id<ASLayoutable>)overlay
{
ASOverlayLayoutNode *n = [super new];
if (n) {
ASDisplayNodeAssertNotNil(node, @"Node that will be overlayed on shouldn't be nil");
ASDisplayNodeAssertNotNil(child, @"Child that will be overlayed on shouldn't be nil");
n->_overlay = overlay;
n->_node = node;
n->_child = child;
}
return n;
}
@ -42,14 +40,14 @@
*/
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
ASLayout *contentsLayout = [_node calculateLayoutThatFits:constrainedSize];
ASLayout *contentsLayout = [_child calculateLayoutThatFits:constrainedSize];
NSMutableArray *layoutChildren = [NSMutableArray arrayWithObject:[ASLayoutChild newWithPosition:{0, 0} layout:contentsLayout]];
if (_overlay) {
ASLayout *overlayLayout = [_overlay calculateLayoutThatFits:{contentsLayout.size, contentsLayout.size}];
[layoutChildren addObject:[ASLayoutChild newWithPosition:{0, 0} layout:overlayLayout]];
}
return [ASLayout newWithNode:self size:contentsLayout.size children:layoutChildren];
return [ASLayout newWithLayoutableObject:self size:contentsLayout.size children:layoutChildren];
}
@end

View File

@ -9,6 +9,7 @@
*/
#import <AsyncDisplayKit/ASLayoutNode.h>
#import <AsyncDisplayKit/ASLayoutable.h>
/**
Ratio layout node
@ -30,6 +31,6 @@
**/
@interface ASRatioLayoutNode : ASLayoutNode
+ (instancetype)newWithRatio:(CGFloat)ratio node:(ASLayoutNode *)node;
+ (instancetype)newWithRatio:(CGFloat)ratio child:(id<ASLayoutable>)child;
@end

View File

@ -16,27 +16,25 @@
#import "ASAssert.h"
#import "ASBaseDefines.h"
#import "ASLayoutNodeSubclass.h"
#import "ASInternalHelpers.h"
@implementation ASRatioLayoutNode
{
CGFloat _ratio;
ASLayoutNode *_node;
id<ASLayoutable> _child;
}
+ (instancetype)newWithRatio:(CGFloat)ratio node:(ASLayoutNode *)node
+ (instancetype)newWithRatio:(CGFloat)ratio child:(id<ASLayoutable>)child
{
ASDisplayNodeAssert(ratio > 0, @"Ratio should be strictly positive, but received %f", ratio);
if (ratio <= 0) {
if (child == nil) {
return nil;
}
ASRatioLayoutNode *n = [super new];
if (n) {
n->_ratio = ratio;
n->_node = node;
n->_child = child;
}
return n;
}
@ -69,10 +67,10 @@
// If there is no max size in *either* dimension, we can't apply the ratio, so just pass our size range through.
const ASSizeRange childRange = (bestSize == sizeOptions.end()) ? constrainedSize : ASSizeRangeMake(*bestSize, *bestSize);
ASLayout *childLayout = [_node calculateLayoutThatFits:childRange];
return [ASLayout newWithNode:self
size:childLayout.size
children:@[[ASLayoutChild newWithPosition:{0, 0} layout:childLayout]]];
ASLayout *childLayout = [_child calculateLayoutThatFits:childRange];
return [ASLayout newWithLayoutableObject:self
size:childLayout.size
children:@[[ASLayoutChild newWithPosition:{0, 0} layout:childLayout]]];
}
@end

View File

@ -73,7 +73,7 @@ typedef struct {
@interface ASStackLayoutNodeChild : NSObject <NSCopying, NSMutableCopying>
@property (nonatomic, readonly) ASLayoutNode *node;
@property (nonatomic, readwrite) id<ASLayoutable> node;
/** Additional space to place before the node in the stacking direction. */
@property (nonatomic, readonly) CGFloat spacingBefore;
/** Additional space to place after the node in the stacking direction. */
@ -96,7 +96,7 @@ typedef struct {
@interface ASMutableStackLayoutNodeChild : ASStackLayoutNodeChild
/** A read-write version of ASStackLayoutNodeChild node property */
@property (nonatomic, readwrite) ASLayoutNode *node;
@property (nonatomic, readwrite) id<ASLayoutable> node;
/** A read-write version of ASStackLayoutNodeChild spacingBefore property */
@property (nonatomic, readwrite) CGFloat spacingBefore;
/** A read-write version of ASStackLayoutNodeChild spacingAfter property */

View File

@ -17,7 +17,6 @@
#import "ASInternalHelpers.h"
#import "ASLayoutNodeUtilities.h"
#import "ASLayoutNodeSubclass.h"
#import "ASStackLayoutNodeUtilities.h"
#import "ASStackPositionedLayout.h"
#import "ASStackUnpositionedLayout.h"
@ -126,9 +125,9 @@
const auto positionedLayout = ASStackPositionedLayout::compute(unpositionedLayout, _style, constrainedSize);
const CGSize finalSize = directionSize(_style.direction, unpositionedLayout.stackDimensionSum, positionedLayout.crossSize);
NSArray *children = [NSArray arrayWithObjects:&positionedLayout.children[0] count:positionedLayout.children.size()];
return [ASLayout newWithNode:self
size:ASSizeRangeClamp(constrainedSize, finalSize)
children:children];
return [ASLayout newWithLayoutableObject:self
size:ASSizeRangeClamp(constrainedSize, finalSize)
children:children];
}
@end

View File

@ -11,7 +11,6 @@
#import "ASStaticLayoutNode.h"
#import "ASLayoutNodeUtilities.h"
#import "ASLayoutNodeSubclass.h"
#import "ASInternalHelpers.h"
@implementation ASStaticLayoutNodeChild
@ -88,7 +87,9 @@
}
}
return [ASLayout newWithNode:self size:ASSizeRangeClamp(constrainedSize, size) children:layoutChildren];
return [ASLayout newWithLayoutableObject:self
size:ASSizeRangeClamp(constrainedSize, size)
children:layoutChildren];
}
@end

View File

@ -13,7 +13,6 @@
#import <numeric>
#import "ASLayoutNodeUtilities.h"
#import "ASLayoutNodeSubclass.h"
#import "ASStackLayoutNodeUtilities.h"
/**
@ -298,7 +297,7 @@ static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStac
const CGFloat exactStackDimension = ASRelativeDimensionResolve(child.flexBasis, stackDimension(style.direction, size));
if (useOptimizedFlexing && isFlexibleInBothDirections(child)) {
return { child, [ASLayout newWithNode:child.node size:{0, 0}] };
return { child, [ASLayout newWithLayoutableObject:child.node size:{0, 0}] };
} else {
return {
child,

View File

@ -53,12 +53,12 @@ static const ASSizeRange kSize = {{100, 120}, {320, 160}};
ASLayoutNode *layoutNode =
[ASBackgroundLayoutNode
newWithNode:
newWithChild:
[ASCenterLayoutNode
newWithCenteringOptions:options
sizingOptions:sizingOptions
child:[ASCompositeNode newWithDisplayNode:foregroundNode]]
background:[ASCompositeNode newWithDisplayNode:backgroundNode]];
child:foregroundNode]
background:backgroundNode];
[self testLayoutNode:layoutNode
sizeRange:kSize
@ -102,14 +102,14 @@ static NSString *suffixForCenteringOptions(ASCenterLayoutNodeCenteringOptions ce
sizingOptions:{}
child:
[ASBackgroundLayoutNode
newWithNode:
newWithChild:
[ASStackLayoutNode
newWithStyle:{}
children:@[[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:foregroundNode];
mutableChild.node = foregroundNode;
mutableChild.flexGrow = YES;
}]]]
background: [ASCompositeNode newWithDisplayNode:backgroundNode]]];
background:backgroundNode]];
[self testLayoutNode:layoutNode sizeRange:kSize subnodes:@[backgroundNode, foregroundNode] identifier:nil];
}

View File

@ -63,11 +63,8 @@ static NSString *nameForInsets(UIEdgeInsets insets)
ASLayoutNode *layoutNode =
[ASBackgroundLayoutNode
newWithNode:
[ASInsetLayoutNode
newWithInsets:insets
node:[ASCompositeNode newWithDisplayNode:foregroundNode]]
background:[ASCompositeNode newWithDisplayNode:backgroundNode]];
newWithChild:[ASInsetLayoutNode newWithInsets:insets child:foregroundNode]
background:backgroundNode];
static ASSizeRange kVariableSize = {{0, 0}, {300, 300}};
[self testLayoutNode:layoutNode
@ -87,11 +84,8 @@ static NSString *nameForInsets(UIEdgeInsets insets)
ASLayoutNode *layoutNode =
[ASBackgroundLayoutNode
newWithNode:
[ASInsetLayoutNode
newWithInsets:insets
node:[ASCompositeNode newWithDisplayNode:foregroundNode]]
background:[ASCompositeNode newWithDisplayNode:backgroundNode]];
newWithChild:[ASInsetLayoutNode newWithInsets:insets child:foregroundNode]
background:backgroundNode];
static ASSizeRange kFixedSize = {{300, 300}, {300, 300}};
[self testLayoutNode:layoutNode
@ -112,11 +106,8 @@ static NSString *nameForInsets(UIEdgeInsets insets)
ASLayoutNode *layoutNode =
[ASBackgroundLayoutNode
newWithNode:
[ASInsetLayoutNode
newWithInsets:insets
node:[ASCompositeNode newWithDisplayNode:foregroundNode]]
background:[ASCompositeNode newWithDisplayNode:backgroundNode]];
newWithChild:[ASInsetLayoutNode newWithInsets:insets child:foregroundNode]
background:backgroundNode];
static ASSizeRange kFixedSize = {{300, 300}, {300, 300}};
[self testLayoutNode:layoutNode

View File

@ -7,7 +7,8 @@
//
#import "ASSnapshotTestCase.h"
#import "ASCompositeNode.h"
@class ASLayoutNode;
@interface ASLayoutNodeSnapshotTestCase: ASSnapshotTestCase
/**
@ -18,7 +19,7 @@
@param identifier An optional identifier, used to identify this snapshot test.
@discussion In order to make the layout node visible, it is embeded to a ASDisplayNode host.
Any display nodes used within the layout (via ASCompositeNode) must be provided.
Any display nodes used within the layout must be provided.
They will be added to the host in the same order as the subnodes array.
*/
- (void)testLayoutNode:(ASLayoutNode *)layoutNode

View File

@ -8,8 +8,8 @@
#import "ASLayoutNodeSnapshotTestsHelper.h"
#import "ASDisplayNode+Subclasses.h"
#import "ASLayoutNodeSubclass.h"
#import "ASDisplayNode.h"
#import "ASLayoutNode.h"
@interface ASTestNode : ASDisplayNode
- (void)setLayoutNodeUnderTest:(ASLayoutNode *)layoutNodeUnderTest sizeRange:(ASSizeRange)sizeRange;
@ -55,7 +55,7 @@
[self measure:_layoutUnderTest.size];
}
- (ASLayout *)calculateLayoutThatFits:(CGSize)constrainedSize
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
return _layoutUnderTest;
}
@ -64,11 +64,11 @@
@implementation ASStaticSizeDisplayNode
- (ASLayout *)calculateLayoutThatFits:(CGSize)constrainedSize
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
return CGSizeEqualToSize(_staticSize, CGSizeZero)
? [super calculateLayoutThatFits:constrainedSize]
: [ASLayout newWithNode:[ASLayoutNode new] size:_staticSize];
: [ASLayout newWithLayoutableObject:self size:ASSizeRangeClamp(constrainedSize, _staticSize)];
}
@end

View File

@ -34,12 +34,12 @@ static const ASSizeRange kSize = {{320, 320}, {320, 320}};
ASLayoutNode *layoutNode =
[ASOverlayLayoutNode
newWithNode:[ASCompositeNode newWithDisplayNode:backgroundNode]
newWithChild:backgroundNode
overlay:
[ASCenterLayoutNode
newWithCenteringOptions:ASCenterLayoutNodeCenteringXY
sizingOptions:{}
child:[ASCompositeNode newWithDisplayNode:foregroundNode]]];
child:foregroundNode]];
[self testLayoutNode:layoutNode sizeRange:kSize subnodes:@[backgroundNode, foregroundNode] identifier: nil];
}

View File

@ -30,9 +30,7 @@ static const ASSizeRange kFixedSize = {{0, 0}, {100, 100}};
ASStaticSizeDisplayNode *subnode = ASDisplayNodeWithBackgroundColor([UIColor greenColor]);
subnode.staticSize = childNodeSize;
ASLayoutNode *layoutNode = [ASRatioLayoutNode
newWithRatio:ratio
node:[ASCompositeNode newWithDisplayNode:subnode]];
ASLayoutNode *layoutNode = [ASRatioLayoutNode newWithRatio:ratio child:subnode];
[self testLayoutNode:layoutNode sizeRange:kFixedSize subnodes:@[subnode] identifier:identifier];
}

View File

@ -26,10 +26,10 @@
self.recordMode = NO;
}
static ASStackLayoutNodeChild *flexChild(ASLayoutNode *n, BOOL flex)
static ASStackLayoutNodeChild *flexChild(id<ASLayoutable> child, BOOL flex)
{
return [ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = n;
mutableChild.node = child;
mutableChild.flexGrow = flex;
mutableChild.flexShrink = flex;
}];
@ -64,9 +64,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
};
NSArray *subnodes = defaultSubnodesWithSameSize({50, 50});
NSArray *children = @[
flexChild([ASCompositeNode newWithDisplayNode:subnodes[0]], flex),
flexChild([ASCompositeNode newWithDisplayNode:subnodes[1]], flex),
flexChild([ASCompositeNode newWithDisplayNode:subnodes[2]], flex)
flexChild(subnodes[0], flex),
flexChild(subnodes[1], flex),
flexChild(subnodes[2], flex)
];
[self testStackLayoutNodeWithStyle:style children:children sizeRange:sizeRange subnodes:subnodes identifier:identifier];
@ -82,8 +82,8 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
ASLayoutNode *layoutNode =
[ASBackgroundLayoutNode
newWithNode:[ASStackLayoutNode newWithStyle:style children:children]
background:[ASCompositeNode newWithDisplayNode:backgroundNode]];
newWithChild:[ASStackLayoutNode newWithStyle:style children:children]
background:backgroundNode];
NSMutableArray *newSubnodes = [NSMutableArray arrayWithObject:backgroundNode];
[newSubnodes addObjectsFromArray:subnodes];
@ -118,15 +118,15 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
// After flexShrink-able children are all clamped to zero, the sum of their widths is 100px.
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
mutableChild.flexShrink = NO;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.flexShrink = YES;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.flexShrink = NO;
}]
];
@ -145,9 +145,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {50, 50};
NSArray *children = @[
flexChild([ASCompositeNode newWithDisplayNode:subnodes[0]], YES),
flexChild([ASCompositeNode newWithDisplayNode:subnodes[1]], YES),
flexChild([ASCompositeNode newWithDisplayNode:subnodes[2]], YES)
flexChild(subnodes[0], YES),
flexChild(subnodes[1], YES),
flexChild(subnodes[2], YES)
];
// width 300px; height 0-150px.
@ -170,13 +170,13 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
}]
];
@ -203,13 +203,13 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
}]
];
// width 0-300px; height 300px
@ -226,9 +226,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
ASLayoutNode *layoutNode =
[ASInsetLayoutNode
newWithInsets:{10, 10, 10 ,10}
node:
child:
[ASBackgroundLayoutNode
newWithNode:
newWithChild:
[ASStackLayoutNode
newWithStyle:{
.direction = ASStackLayoutDirectionVertical,
@ -239,7 +239,7 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
[ASStackLayoutNodeChild new],
[ASStackLayoutNodeChild new]
]]
background:[ASCompositeNode newWithDisplayNode:backgroundNode]]];
background:backgroundNode]];
// width 300px; height 0-300px
static ASSizeRange kVariableHeight = {{300, 0}, {300, 300}};
@ -259,14 +259,14 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.spacingBefore = 10;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.spacingBefore = 20;
}]
];
@ -274,14 +274,14 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.spacingAfter = 10;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.spacingAfter = 20;
}]
];
@ -290,15 +290,15 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
style.spacing = 10;
children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.spacingBefore = -10;
mutableChild.spacingAfter = -10;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
}]
];
[self testStackLayoutNodeWithStyle:style children:children sizeRange:kAnySize subnodes:subnodes identifier:@"spacingBalancedOut"];
@ -318,15 +318,15 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
mutableChild.spacingBefore = 0;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.spacingBefore = 20;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.spacingBefore = 30;
}]
];
@ -348,15 +348,13 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASRatioLayoutNode
newWithRatio:1.5
node:[ASCompositeNode newWithDisplayNode:subnodes[0]]];
mutableChild.node = [ASRatioLayoutNode newWithRatio:1.5 child:subnodes[0]];
mutableChild.flexBasis = ASRelativeDimensionMakeWithPercent(1);
mutableChild.flexGrow = YES;
mutableChild.flexShrink = YES;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
}]
];
static ASSizeRange kFixedWidth = {{150, 0}, {150, INFINITY}};
@ -379,11 +377,11 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
mutableChild.flexShrink = YES;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.flexShrink = YES;
}],
];
@ -404,10 +402,10 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.alignSelf = ASStackLayoutAlignSelfCenter;
}],
];
@ -430,15 +428,15 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
mutableChild.spacingBefore = 0;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.spacingBefore = 20;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.spacingBefore = 30;
}]
];
@ -461,15 +459,15 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
mutableChild.spacingBefore = 0;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.spacingBefore = 20;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.spacingBefore = 30;
}]
];
@ -492,15 +490,15 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
mutableChild.spacingBefore = 0;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.spacingBefore = 20;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.spacingBefore = 30;
}]
];
@ -523,15 +521,15 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
mutableChild.spacingBefore = 0;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.spacingBefore = 20;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.spacingBefore = 30;
}]
];
@ -555,15 +553,15 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
mutableChild.spacingBefore = 0;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.spacingBefore = 20;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.spacingBefore = 30;
}]
];
@ -589,17 +587,17 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
mutableChild.flexGrow = YES;
mutableChild.flexBasis = ASRelativeDimensionMakeWithPoints(10);
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.flexGrow = YES;
mutableChild.flexBasis = ASRelativeDimensionMakeWithPoints(10);
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.flexGrow = YES;
mutableChild.flexBasis = ASRelativeDimensionMakeWithPoints(10);
}]
@ -619,18 +617,18 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *subnodes = defaultSubnodesWithSameSize({50, 50});
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
mutableChild.flexGrow = YES;
// This should override the intrinsic size of 50pts and instead compute to 50% = 100pts.
// The result should be that the red box is twice as wide as the blue and gree boxes after flexing.
mutableChild.flexBasis = ASRelativeDimensionMakeWithPercent(0.5);
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.flexGrow = YES;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.flexGrow = YES;
}]
];
@ -649,15 +647,15 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
mutableChild.flexBasis = ASRelativeDimensionMakeWithPoints(20);
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.flexBasis = ASRelativeDimensionMakeWithPoints(20);
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.flexBasis = ASRelativeDimensionMakeWithPoints(20);
}]
];
@ -679,26 +677,23 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
// Instead it should be stretched to 300 points tall, matching the red child and not overlapping the green inset.
ASLayoutNode *layoutNode =
[ASBackgroundLayoutNode
newWithNode:
newWithChild:
[ASInsetLayoutNode
newWithInsets:UIEdgeInsetsMake(10, 10, 10, 10)
node:
[ASStackLayoutNode
newWithStyle:{
child:
[ASStackLayoutNode
newWithStyle:{
.direction = ASStackLayoutDirectionHorizontal,
.alignItems = ASStackLayoutAlignItemsStretch,
}
children:
@[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
}],
flexChild([ASRatioLayoutNode
newWithRatio:1.0
node:[ASCompositeNode newWithDisplayNode:subnodes[2]]],
YES),
]]]
background:[ASCompositeNode newWithDisplayNode:subnodes[0]]];
}
children:
@[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = subnodes[1];
}],
flexChild([ASRatioLayoutNode newWithRatio:1.0 child:subnodes[2]], YES),
]]]
background:subnodes[0]];
static ASSizeRange kSize = {{300, 0}, {300, INFINITY}};
[self testLayoutNode:layoutNode sizeRange:kSize subnodes:subnodes identifier:nil];
@ -715,15 +710,15 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize)
NSArray *children = @[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[0]];
mutableChild.node = subnodes[0];
mutableChild.flexShrink = YES;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[1]];
mutableChild.node = subnodes[1];
mutableChild.flexShrink = NO;
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableChild) {
mutableChild.node = [ASCompositeNode newWithDisplayNode:subnodes[2]];
mutableChild.node = subnodes[2];
mutableChild.flexShrink = YES;
}]
];

View File

@ -15,7 +15,6 @@
#import <AsyncDisplayKit/ASHighlightOverlayLayer.h>
#import <AsyncDisplayKit/ASInsetLayoutNode.h>
#import <AsyncDisplayKit/ASCompositeNode.h>
static CGFloat kTextPadding = 10.0f;
static NSString *kLinkAttributeName = @"PlaceKittenNodeLinkAttributeName";
@ -72,11 +71,12 @@ static NSString *kLinkAttributeName = @"PlaceKittenNodeLinkAttributeName";
[super didLoad];
}
- (ASLayoutNode *)layoutNodeThatFits:(CGSize)constrainedSize
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
// called on a background thread. custom nodes must call -measure: on their subnodes in -calculateSizeThatFits:
UIEdgeInsets insets = UIEdgeInsetsMake(kTextPadding, kTextPadding, kTextPadding, kTextPadding);
return [ASInsetLayoutNode newWithInsets:insets node:[ASCompositeNode newWithDisplayNode:_textNode]];
id<ASLayoutable> layoutSpec = [ASInsetLayoutNode newWithInsets:insets child:_textNode];
return [layoutSpec calculateLayoutThatFits:constrainedSize];
}
#pragma mark -

View File

@ -15,7 +15,6 @@
#import <AsyncDisplayKit/ASStackLayoutNode.h>
#import <AsyncDisplayKit/ASInsetLayoutNode.h>
#import <AsyncDisplayKit/ASCompositeNode.h>
static const CGFloat kImageSize = 80.0f;
static const CGFloat kOuterPadding = 16.0f;
@ -128,12 +127,12 @@ static const CGFloat kInnerPadding = 10.0f;
NSParagraphStyleAttributeName: style };
}
- (ASLayoutNode *)layoutNodeThatFits:(CGSize)constrainedSize
- (ASLayout *)calculateLayoutThatFits:(ASSizeRange)constrainedSize
{
return
id<ASLayoutable> layoutSpec =
[ASInsetLayoutNode
newWithInsets:UIEdgeInsetsMake(kOuterPadding, kOuterPadding, kOuterPadding, kOuterPadding)
node:
child:
[ASStackLayoutNode
newWithStyle:{
.direction = ASStackLayoutDirectionHorizontal,
@ -142,14 +141,15 @@ static const CGFloat kInnerPadding = 10.0f;
children:
@[
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableCopy) {
mutableCopy.node = [ASRatioLayoutNode newWithRatio:1.0 node:[ASCompositeNode newWithDisplayNode:_imageNode]];
mutableCopy.node = [ASRatioLayoutNode newWithRatio:1.0 child:_imageNode];
mutableCopy.flexBasis = ASRelativeDimensionMakeWithPoints(kImageSize);
}],
[ASStackLayoutNodeChild newWithInitializer:^(ASMutableStackLayoutNodeChild *mutableCopy) {
mutableCopy.node = [ASCompositeNode newWithDisplayNode:_textNode];
mutableCopy.node = _textNode;
mutableCopy.flexShrink = true;
}]
]]];
return [layoutSpec calculateLayoutThatFits:constrainedSize];
}
- (void)layout