Hide ASLayoutOptions from the user

This commit is contained in:
rcancro
2015-08-28 14:30:50 -07:00
parent 15b3fd6eab
commit cbaf178950
19 changed files with 344 additions and 129 deletions

View File

@@ -233,12 +233,18 @@
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, ); }; };
9C6BB3B21B8CC9C200F13F52 /* ASStaticLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C6BB3B31B8CC9C200F13F52 /* ASStaticLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C5FA3511B8F6ADF00A62714 /* ASLayoutOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C5FA3521B8F6ADF00A62714 /* ASLayoutOptions.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C5FA3531B8F6ADF00A62714 /* ASLayoutOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.m */; };
9C5FA3541B8F6ADF00A62714 /* ASLayoutOptions.m in Sources */ = {isa = PBXBuildFile; fileRef = 9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.m */; };
9C5FA35D1B90C9A500A62714 /* ASLayoutOptionsPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FA35B1B90C9A500A62714 /* ASLayoutOptionsPrivate.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C5FA35E1B90C9A500A62714 /* ASLayoutOptionsPrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FA35B1B90C9A500A62714 /* ASLayoutOptionsPrivate.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C5FA35F1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C5FA35C1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm */; };
9C5FA3601B90C9A500A62714 /* ASLayoutOptionsPrivate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 9C5FA35C1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm */; };
9C5FA3631B91007100A62714 /* ASLayoutablePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FA3611B91007100A62714 /* ASLayoutablePrivate.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C5FA3641B91007100A62714 /* ASLayoutablePrivate.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C5FA3611B91007100A62714 /* ASLayoutablePrivate.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C6BB3B21B8CC9C200F13F52 /* ASStaticLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */; settings = {ATTRIBUTES = (Public, ); }; };
9C6BB3B31B8CC9C200F13F52 /* ASStaticLayoutable.h in Headers */ = {isa = PBXBuildFile; fileRef = 9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.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, ); }; };
@@ -475,7 +481,7 @@
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>"; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
058D09E0195D050800B7D73C /* ASTextNode.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; lineEnding = 0; path = ASTextNode.mm; sourceTree = "<group>"; };
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>"; };
@@ -586,9 +592,12 @@
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>"; };
9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStaticLayoutable.h; path = AsyncDisplayKit/Layout/ASStaticLayoutable.h; sourceTree = "<group>"; };
9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutOptions.h; path = AsyncDisplayKit/Layout/ASLayoutOptions.h; sourceTree = "<group>"; };
9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ASLayoutOptions.m; path = AsyncDisplayKit/Layout/ASLayoutOptions.m; sourceTree = "<group>"; };
9C5FA35B1B90C9A500A62714 /* ASLayoutOptionsPrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutOptionsPrivate.h; path = AsyncDisplayKit/Layout/ASLayoutOptionsPrivate.h; sourceTree = "<group>"; };
9C5FA35C1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = ASLayoutOptionsPrivate.mm; path = AsyncDisplayKit/Layout/ASLayoutOptionsPrivate.mm; sourceTree = "<group>"; };
9C5FA3611B91007100A62714 /* ASLayoutablePrivate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASLayoutablePrivate.h; path = AsyncDisplayKit/Private/ASLayoutablePrivate.h; sourceTree = "<group>"; };
9C6BB3B01B8CC9C200F13F52 /* ASStaticLayoutable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ASStaticLayoutable.h; path = AsyncDisplayKit/Layout/ASStaticLayoutable.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>"; };
@@ -992,6 +1001,7 @@
ACF6ED0B1B17843500DA7C62 /* ASLayout.h */,
ACF6ED0C1B17843500DA7C62 /* ASLayout.mm */,
ACF6ED111B17843500DA7C62 /* ASLayoutable.h */,
9C5FA3611B91007100A62714 /* ASLayoutablePrivate.h */,
ACF6ED0D1B17843500DA7C62 /* ASLayoutSpec.h */,
ACF6ED0E1B17843500DA7C62 /* ASLayoutSpec.mm */,
ACF6ED121B17843500DA7C62 /* ASOverlayLayoutSpec.h */,
@@ -1009,6 +1019,8 @@
9C3061051B857EC400D0530B /* ASBaselineLayoutSpec.mm */,
9C5FA34F1B8F6ADF00A62714 /* ASLayoutOptions.h */,
9C5FA3501B8F6ADF00A62714 /* ASLayoutOptions.m */,
9C5FA35B1B90C9A500A62714 /* ASLayoutOptionsPrivate.h */,
9C5FA35C1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm */,
);
name = Layout;
path = ..;
@@ -1085,6 +1097,7 @@
058D0A4F195D05CB00B7D73C /* ASImageNode.h in Headers */,
058D0A50195D05CB00B7D73C /* ASImageNode.mm in Headers */,
058D0A51195D05CB00B7D73C /* ASTextNode.h in Headers */,
9C5FA35D1B90C9A500A62714 /* ASLayoutOptionsPrivate.h in Headers */,
296A0A2E1A9516B2005ACEAA /* ASBatchFetching.h in Headers */,
058D0A52195D05CB00B7D73C /* ASTextNode.mm in Headers */,
055F1A3819ABD413004DAFF1 /* ASRangeController.h in Headers */,
@@ -1127,6 +1140,7 @@
18C2ED7E1B9B7DE800F627B3 /* ASCollectionNode.h in Headers */,
058D0A6C195D05EC00B7D73C /* _ASAsyncTransactionContainer.m in Headers */,
6BDC61F61979037800E50D21 /* AsyncDisplayKit.h in Headers */,
9C5FA3631B91007100A62714 /* ASLayoutablePrivate.h in Headers */,
058D0A6D195D05EC00B7D73C /* _ASAsyncTransactionGroup.h in Headers */,
058D0A6E195D05EC00B7D73C /* _ASAsyncTransactionGroup.m in Headers */,
205F0E1D1B373A2C007741D0 /* ASCollectionViewLayoutController.h in Headers */,
@@ -1179,6 +1193,7 @@
B35062321B010EFD0018CF92 /* ASTextNodeShadower.h in Headers */,
34EFC7651B701CCC00AD841F /* ASRelativeSize.h in Headers */,
B35062431B010EFD0018CF92 /* UIView+ASConvenience.h in Headers */,
9C5FA35E1B90C9A500A62714 /* ASLayoutOptionsPrivate.h in Headers */,
B31A241E1B0114FD0016AE7A /* AsyncDisplayKit.h in Headers */,
B350622D1B010EFD0018CF92 /* ASScrollDirection.h in Headers */,
B35061FB1B010EFD0018CF92 /* ASDisplayNode.h in Headers */,
@@ -1267,6 +1282,7 @@
B35062591B010F070018CF92 /* ASBaseDefines.h in Headers */,
B35062191B010EFD0018CF92 /* ASDealloc2MainObject.h in Headers */,
B350620F1B010EFD0018CF92 /* _ASDisplayLayer.h in Headers */,
9C5FA3641B91007100A62714 /* ASLayoutablePrivate.h in Headers */,
B35062531B010EFD0018CF92 /* ASImageNode+CGExtras.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1472,6 +1488,7 @@
058D0A18195D050800B7D73C /* _ASDisplayLayer.mm in Sources */,
ACF6ED321B17843500DA7C62 /* ASStaticLayoutSpec.mm in Sources */,
9C5FA3531B8F6ADF00A62714 /* ASLayoutOptions.m in Sources */,
9C5FA35F1B90C9A500A62714 /* ASLayoutOptionsPrivate.mm in Sources */,
ACF6ED2C1B17843500DA7C62 /* ASOverlayLayoutSpec.mm in Sources */,
058D0A2C195D050800B7D73C /* ASSentinel.m in Sources */,
205F0E221B376416007741D0 /* CGRect+ASConvenience.m in Sources */,
@@ -1584,6 +1601,7 @@
B35062471B010EFD0018CF92 /* ASBatchFetching.m in Sources */,
B350624E1B010EFD0018CF92 /* ASDisplayNode+AsyncDisplay.mm in Sources */,
34EFC76F1B701CF700AD841F /* ASRatioLayoutSpec.mm in Sources */,
9C5FA3601B90C9A500A62714 /* ASLayoutOptionsPrivate.mm in Sources */,
34EFC7681B701CDE00AD841F /* ASLayout.mm in Sources */,
B35061F61B010EFD0018CF92 /* ASCollectionView.mm in Sources */,
34EFC75C1B701BD200AD841F /* ASDimension.mm in Sources */,

View File

@@ -9,6 +9,7 @@
#import "ASDisplayNode.h"
#import "ASDisplayNode+Subclasses.h"
#import "ASDisplayNodeInternal.h"
#import "ASLayoutOptionsPrivate.h"
#import <objc/runtime.h>
@@ -41,6 +42,7 @@
@implementation ASDisplayNode
@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis, alignSelf, ascender, descender, sizeRange, layoutPosition, layoutOptions;
@synthesize preferredFrameSize = _preferredFrameSize;
BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector)
@@ -670,11 +672,6 @@ static inline BOOL _ASDisplayNodeIsAncestorOfDisplayNode(ASDisplayNode *possible
return NO;
}
- (id<ASLayoutable>)finalLayoutable
{
return self;
}
/**
* NOTE: It is an error to try to convert between nodes which do not share a common ancestor. This behavior is
* disallowed in UIKit documentation and the behavior is left undefined. The output does not have a rigorously defined
@@ -1852,6 +1849,10 @@ static void _recursivelySetDisplaySuspended(ASDisplayNode *node, CALayer *layer,
return !self.layerBacked && [self.view canPerformAction:action withSender:sender];
}
- (id<ASLayoutable>)finalLayoutable {
return self;
}
@end
@implementation ASDisplayNode (Debugging)

View File

@@ -16,6 +16,9 @@
@interface ASLayoutOptions : NSObject <ASBaselineLayoutable, ASStackLayoutable, ASStaticLayoutable, NSCopying>
+ (void)setDefaultLayoutOptionsClass:(Class)defaultLayoutOptionsClass;
+ (Class)defaultLayoutOptionsClass;
- (instancetype)initWithLayoutable:(id<ASLayoutable>)layoutable;
- (void)setValuesFromLayoutable:(id<ASLayoutable>)layoutable;
@@ -42,7 +45,7 @@
#pragma mark - ASStaticLayoutable
@property (nonatomic, readwrite) ASRelativeSizeRange sizeRange;
@property (nonatomic, readwrite) CGPoint position;
@property (nonatomic, readwrite) CGPoint layoutPosition;
- (void)setupDefaults;

View File

@@ -15,6 +15,18 @@
@implementation ASLayoutOptions
static Class gDefaultLayoutOptionsClass = nil;
+ (void)setDefaultLayoutOptionsClass:(Class)defaultLayoutOptionsClass
{
gDefaultLayoutOptionsClass = defaultLayoutOptionsClass;
}
+ (Class)defaultLayoutOptionsClass
{
return gDefaultLayoutOptionsClass;
}
- (instancetype)initWithLayoutable:(id<ASLayoutable>)layoutable;
{
self = [super init];
@@ -79,7 +91,7 @@
copy.descender = self.descender;
copy.sizeRange = self.sizeRange;
copy.position = self.position;
copy.layoutPosition = self.layoutPosition;
return copy;
}
@@ -98,7 +110,7 @@
_descender = 0;
_sizeRange = ASRelativeSizeRangeMake(ASRelativeSizeMakeWithCGSize(CGSizeZero), ASRelativeSizeMakeWithCGSize(CGSizeZero));
_position = CGPointZero;
_layoutPosition = CGPointZero;
}
// Do this here instead of in Node/Spec subclasses so that custom specs can set default values
@@ -112,7 +124,7 @@
if ([layoutable isKindOfClass:[ASDisplayNode class]]) {
ASDisplayNode *displayNode = (ASDisplayNode *)layoutable;
self.sizeRange = ASRelativeSizeRangeMake(ASRelativeSizeMakeWithCGSize(displayNode.preferredFrameSize), ASRelativeSizeMakeWithCGSize(displayNode.preferredFrameSize));
self.position = displayNode.frame.origin;
self.layoutPosition = displayNode.frame.origin;
}
}

View File

@@ -0,0 +1,30 @@
//
// ASDisplayNode+Layoutable.h
// AsyncDisplayKit
//
// Created by Ricky Cancro on 8/28/15.
// Copyright (c) 2015 Facebook. All rights reserved.
//
#import <AsyncDisplayKit/ASDisplayNode.h>
#import <AsyncDisplayKit/ASLayoutSpec.h>
@interface ASDisplayNode()
{
ASLayoutOptions *_layoutOptions;
}
@end
@interface ASDisplayNode(ASLayoutOptions)<ASLayoutable>
@end
@interface ASLayoutSpec()
{
ASLayoutOptions *_layoutOptions;
}
@end
@interface ASLayoutSpec(ASLayoutOptions)<ASLayoutable>
@end

View File

@@ -0,0 +1,129 @@
//
// ASDisplayNode+Layoutable.m
// AsyncDisplayKit
//
// Created by Ricky Cancro on 8/28/15.
// Copyright (c) 2015 Facebook. All rights reserved.
//
#import "ASLayoutOptionsPrivate.h"
#import <AsyncDisplayKit/ASDisplayNodeInternal.h>
#define ASLayoutOptionsForwarding \
- (ASLayoutOptions *)layoutOptions\
{\
if (_layoutOptions == nil) {\
_layoutOptions = [[[ASLayoutOptions defaultLayoutOptionsClass] alloc] init];\
}\
return _layoutOptions;\
}\
\
- (CGFloat)spacingBefore\
{\
return self.layoutOptions.spacingBefore;\
}\
\
- (void)setSpacingBefore:(CGFloat)spacingBefore\
{\
self.layoutOptions.spacingBefore = spacingBefore;\
}\
\
- (CGFloat)spacingAfter\
{\
return self.layoutOptions.spacingAfter;\
}\
\
- (void)setSpacingAfter:(CGFloat)spacingAfter\
{\
self.layoutOptions.spacingAfter = spacingAfter;\
}\
\
- (BOOL)flexGrow\
{\
return self.layoutOptions.flexGrow;\
}\
\
- (void)setFlexGrow:(BOOL)flexGrow\
{\
self.layoutOptions.flexGrow = flexGrow;\
}\
\
- (BOOL)flexShrink\
{\
return self.layoutOptions.flexShrink;\
}\
\
- (void)setFlexShrink:(BOOL)flexShrink\
{\
self.layoutOptions.flexShrink = flexShrink;\
}\
\
- (ASRelativeDimension)flexBasis\
{\
return self.layoutOptions.flexBasis;\
}\
\
- (void)setFlexBasis:(ASRelativeDimension)flexBasis\
{\
self.layoutOptions.flexBasis = flexBasis;\
}\
\
- (ASStackLayoutAlignSelf)alignSelf\
{\
return self.layoutOptions.alignSelf;\
}\
\
- (void)setAlignSelf:(ASStackLayoutAlignSelf)alignSelf\
{\
self.layoutOptions.alignSelf = alignSelf;\
}\
\
- (CGFloat)ascender\
{\
return self.layoutOptions.ascender;\
}\
\
- (void)setAscender:(CGFloat)ascender\
{\
self.layoutOptions.ascender = ascender;\
}\
\
- (CGFloat)descender\
{\
return self.layoutOptions.descender;\
}\
\
- (void)setDescender:(CGFloat)descender\
{\
self.layoutOptions.descender = descender;\
}\
\
- (ASRelativeSizeRange)sizeRange\
{\
return self.layoutOptions.sizeRange;\
}\
\
- (void)setSizeRange:(ASRelativeSizeRange)sizeRange\
{\
self.layoutOptions.sizeRange = sizeRange;\
}\
\
- (CGPoint)layoutPosition\
{\
return self.layoutOptions.layoutPosition;\
}\
\
- (void)setLayoutPosition:(CGPoint)position\
{\
self.layoutOptions.layoutPosition = position;\
}\
@implementation ASDisplayNode(ASLayoutOptions)
ASLayoutOptionsForwarding
@end
@implementation ASLayoutSpec(ASLayoutOptions)
ASLayoutOptionsForwarding
@end

View File

@@ -30,8 +30,8 @@
- (id<ASLayoutable>)childForIdentifier:(NSString *)identifier;
- (NSArray *)children;
+ (ASLayoutOptions *)layoutOptionsForChild:(id<ASLayoutable>)child;
+ (void)associateLayoutOptions:(ASLayoutOptions *)layoutOptions withChild:(id<ASLayoutable>)child;
+ (void)setLayoutOptionsClass:(Class)layoutOptionsClass;
//+ (ASLayoutOptions *)layoutOptionsForChild:(id<ASLayoutable>)child;
//+ (void)associateLayoutOptions:(ASLayoutOptions *)layoutOptions withChild:(id<ASLayoutable>)child;
//+ (void)setLayoutOptionsClass:(Class)layoutOptionsClass;
@end

View File

@@ -15,6 +15,8 @@
#import "ASInternalHelpers.h"
#import "ASLayout.h"
#import "ASLayoutOptions.h"
#import "ASLayoutOptionsPrivate.h"
#import <objc/runtime.h>
@@ -27,6 +29,7 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
@implementation ASLayoutSpec
@dynamic spacingAfter, spacingBefore, flexGrow, flexShrink, flexBasis, alignSelf, ascender, descender, sizeRange, layoutPosition, layoutOptions;
@synthesize layoutChildren = _layoutChildren;
- (instancetype)init
@@ -71,16 +74,20 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
NSMutableArray *finalChildren = [NSMutableArray arrayWithCapacity:children.count];
for (id<ASLayoutable> child in children) {
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:child];
id<ASLayoutable> finalLayoutable = [child finalLayoutable];
if ([child respondsToSelector:@selector(finalLayoutable)]) {
id<ASLayoutable> finalLayoutable = [child performSelector:@selector(finalLayoutable)];
layoutOptions.isMutable = NO;
if (finalLayoutable != child) {
ASLayoutOptions *finalLayoutOptions = [layoutOptions copy];
finalLayoutOptions.isMutable = NO;
[ASLayoutSpec associateLayoutOptions:finalLayoutOptions withChild:finalLayoutable];
[finalChildren addObject:finalLayoutable];
}
} else {
[finalChildren addObject:child];
}
[finalChildren addObject:finalLayoutable];
}
self.layoutChildren[kDefaultChildrenKey] = [NSArray arrayWithArray:finalChildren];

View File

@@ -9,8 +9,10 @@
*/
#import <AsyncDisplayKit/ASDimension.h>
#import <AsyncDisplayKit/ASRelativeSize.h>
#import <AsyncDisplayKit/ASStackLayoutDefines.h>
#import <AsyncDisplayKit/ASLayoutOptions.h>
#import <AsyncDisplayKit/ASLayoutablePrivate.h>
@class ASLayout;
@class ASLayoutSpec;
@@ -20,7 +22,7 @@
* so that instances of that class can be used to build layout trees. The protocol also provides information
* about how an object should be laid out within an ASStackLayoutSpec.
*/
@protocol ASLayoutable <NSObject>
@protocol ASLayoutable <ASLayoutablePrivate>
/**
* @abstract Calculate a layout based on given size range.
@@ -31,16 +33,17 @@
*/
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize;
/**
@abstract Give this object a last chance to add itself to a container ASLayoutable (most likely an ASLayoutSpec) before
being added to a ASLayoutSpec.
@property (nonatomic, readwrite) CGFloat spacingBefore;
@property (nonatomic, readwrite) CGFloat spacingAfter;
@property (nonatomic, readwrite) BOOL flexGrow;
@property (nonatomic, readwrite) BOOL flexShrink;
@property (nonatomic, readwrite) ASRelativeDimension flexBasis;
@property (nonatomic, readwrite) ASStackLayoutAlignSelf alignSelf;
For example, consider a node whose superclass is laid out via calculateLayoutThatFits:. The subclass cannot implement
layoutSpecThatFits: since its ASLayout is already being created by calculateLayoutThatFits:. By implementing this method
a subclass can wrap itself in an ASLayoutSpec right before it is added to a layout spec.
@property (nonatomic, readwrite) CGFloat ascender;
@property (nonatomic, readwrite) CGFloat descender;
It is rare that a class will need to implement this method.
*/
- (id<ASLayoutable>)finalLayoutable;
@property (nonatomic, readwrite) ASRelativeSizeRange sizeRange;
@property (nonatomic, readwrite) CGPoint layoutPosition;
@end

View File

@@ -11,6 +11,8 @@
#import "ASStaticLayoutSpec.h"
#import "ASLayoutSpecUtilities.h"
#import "ASLayoutOptions.h"
#import "ASLayoutOptionsPrivate.h"
#import "ASInternalHelpers.h"
#import "ASLayout.h"
#import "ASStaticLayoutable.h"
@@ -45,16 +47,16 @@
NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:self.children.count];
for (id<ASLayoutable> child in self.children) {
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:child];
ASLayoutOptions *layoutOptions = child.layoutOptions;
CGSize autoMaxSize = {
constrainedSize.max.width - layoutOptions.position.x,
constrainedSize.max.height - layoutOptions.position.y
constrainedSize.max.width - layoutOptions.layoutPosition.x,
constrainedSize.max.height - layoutOptions.layoutPosition.y
};
ASSizeRange childConstraint = ASRelativeSizeRangeEqualToRelativeSizeRange(ASRelativeSizeRangeUnconstrained, layoutOptions.sizeRange)
? ASSizeRangeMake({0, 0}, autoMaxSize)
: ASRelativeSizeRangeResolve(layoutOptions.sizeRange, size);
ASLayout *sublayout = [child measureWithSizeRange:childConstraint];
sublayout.position = layoutOptions.position;
sublayout.position = layoutOptions.layoutPosition;
[sublayouts addObject:sublayout];
}

View File

@@ -18,6 +18,6 @@
@property (nonatomic, assign) ASRelativeSizeRange sizeRange;
/** The position of this object within its parent spec. */
@property (nonatomic, assign) CGPoint position;
@property (nonatomic, assign) CGPoint layoutPosition;
@end

View File

@@ -12,17 +12,19 @@
#import "ASLayoutSpecUtilities.h"
#import "ASStackLayoutSpecUtilities.h"
#import "ASLayoutOptions.h"
static CGFloat baselineForItem(const ASBaselineLayoutSpecStyle &style,
const ASLayout *layout) {
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:layout.layoutableObject];
__weak id<ASLayoutable> child = layout.layoutableObject;
switch (style.baselineAlignment) {
case ASBaselineLayoutBaselineAlignmentNone:
return 0;
case ASBaselineLayoutBaselineAlignmentFirst:
return layoutOptions.ascender;
return child.layoutOptions.ascender;
case ASBaselineLayoutBaselineAlignmentLast:
return layout.size.height + layoutOptions.descender;
return layout.size.height + child.layoutOptions.descender;
}
}
@@ -33,10 +35,10 @@ static CGFloat baselineOffset(const ASBaselineLayoutSpecStyle &style,
const CGFloat maxBaseline)
{
if (style.stackLayoutStyle.direction == ASStackLayoutDirectionHorizontal) {
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:l.layoutableObject];
__weak id<ASLayoutable> child = l.layoutableObject;
switch (style.baselineAlignment) {
case ASBaselineLayoutBaselineAlignmentFirst:
return maxAscender - layoutOptions.ascender;
return maxAscender - child.layoutOptions.ascender;
case ASBaselineLayoutBaselineAlignmentLast:
return maxBaseline - baselineForItem(style, l);
case ASBaselineLayoutBaselineAlignmentNone:
@@ -90,11 +92,9 @@ ASBaselinePositionedLayout ASBaselinePositionedLayout::compute(const ASStackPosi
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){
ASLayoutOptions *layoutOptionsA = [ASLayoutSpec layoutOptionsForChild:a.layoutableObject];
ASLayoutOptions *layoutOptionsB = [ASLayoutSpec layoutOptionsForChild:b.layoutableObject];
return layoutOptionsA.ascender < layoutOptionsB.ascender;
return a.layoutableObject.layoutOptions.ascender < b.layoutableObject.layoutOptions.ascender;
});
const CGFloat maxAscender = baselineIt == positionedLayout.sublayouts.end() ? 0 : [ASLayoutSpec layoutOptionsForChild:(*ascenderIt).layoutableObject].ascender;
const CGFloat maxAscender = baselineIt == positionedLayout.sublayouts.end() ? 0 : (*ascenderIt).layoutableObject.layoutOptions.ascender;
/*
Step 3: Take each child and update its layout position based on the baseline offset.
@@ -107,8 +107,8 @@ ASBaselinePositionedLayout ASBaselinePositionedLayout::compute(const ASStackPosi
CGPoint p = CGPointZero;
BOOL first = YES;
auto stackedChildren = AS::map(positionedLayout.sublayouts, [&](ASLayout *l) -> ASLayout *{
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:l.layoutableObject];
p = p + directionPoint(stackStyle.direction, layoutOptions.spacingBefore, 0);
__weak id<ASLayoutable> child = l.layoutableObject;
p = p + directionPoint(stackStyle.direction, child.layoutOptions.spacingBefore, 0);
if (first) {
// if this is the first item use the previously computed start point
p = l.position;
@@ -125,9 +125,9 @@ ASBaselinePositionedLayout ASBaselinePositionedLayout::compute(const ASStackPosi
// node from baselines and not bounding boxes.
CGFloat spacingAfterBaseline = 0;
if (stackStyle.direction == ASStackLayoutDirectionVertical) {
spacingAfterBaseline = layoutOptions.descender;
spacingAfterBaseline = child.layoutOptions.descender;
}
p = p + directionPoint(stackStyle.direction, stackDimension(stackStyle.direction, l.size) + layoutOptions.spacingAfter + spacingAfterBaseline, 0);
p = p + directionPoint(stackStyle.direction, stackDimension(stackStyle.direction, l.size) + child.layoutOptions.spacingAfter + spacingAfterBaseline, 0);
return l;
});
@@ -157,7 +157,7 @@ ASBaselinePositionedLayout ASBaselinePositionedLayout::compute(const ASStackPosi
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 : [ASLayoutSpec layoutOptionsForChild:(*descenderIt).layoutableObject].descender;
const CGFloat minDescender = descenderIt == stackedChildren.end() ? 0 : (*descenderIt).layoutableObject.layoutOptions.descender;
return {stackedChildren, crossSize, maxAscender, minDescender};
}

View File

@@ -17,6 +17,7 @@
#import "ASDisplayNode.h"
#import "ASSentinel.h"
#import "ASThread.h"
#import "ASLayoutOptions.h"
BOOL ASDisplayNodeSubclassOverridesSelector(Class subclass, SEL selector);
void ASDisplayNodePerformBlockOnMainThread(void (^block)());
@@ -153,6 +154,8 @@ typedef NS_OPTIONS(NSUInteger, ASDisplayNodeMethodOverrides) {
@property (nonatomic, assign) CGFloat contentsScaleForDisplay;
- (id<ASLayoutable>)finalLayoutable;
@end
@interface UIView (ASDisplayNodeInternal)

View File

@@ -0,0 +1,16 @@
//
// ASLayoutablePrivate.h
// AsyncDisplayKit
//
// Created by Ricky Cancro on 8/28/15.
// Copyright (c) 2015 Facebook. All rights reserved.
//
#import <Foundation/Foundation.h>
@class ASLayoutSpec;
@class ASLayoutOptions;
@protocol ASLayoutablePrivate <NSObject>
- (ASLayoutSpec *)finalLayoutable;
@property (nonatomic, strong, readonly) ASLayoutOptions *layoutOptions;
@end

View File

@@ -14,13 +14,13 @@
#import "ASLayoutSpecUtilities.h"
#import "ASStackLayoutSpecUtilities.h"
#import "ASLayoutable.h"
#import "ASLayoutOptions.h"
static CGFloat crossOffset(const ASStackLayoutSpecStyle &style,
const ASStackUnpositionedItem &l,
const CGFloat crossSize)
{
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:l.child];
switch (alignment(layoutOptions.alignSelf, style.alignItems)) {
switch (alignment(l.child.layoutOptions.alignSelf, style.alignItems)) {
case ASStackLayoutAlignItemsEnd:
return crossSize - crossDimension(style.direction, l.layout.size);
case ASStackLayoutAlignItemsCenter:
@@ -49,15 +49,14 @@ static ASStackPositionedLayout stackedLayout(const ASStackLayoutSpecStyle &style
CGPoint p = directionPoint(style.direction, offset, 0);
BOOL first = YES;
auto stackedChildren = AS::map(unpositionedLayout.items, [&](const ASStackUnpositionedItem &l) -> ASLayout *{
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:l.child];
p = p + directionPoint(style.direction, layoutOptions.spacingBefore, 0);
p = p + directionPoint(style.direction, l.child.layoutOptions.spacingBefore, 0);
if (!first) {
p = p + directionPoint(style.direction, style.spacing, 0);
}
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) + layoutOptions.spacingAfter, 0);
p = p + directionPoint(style.direction, stackDimension(style.direction, l.layout.size) + l.child.layoutOptions.spacingAfter, 0);
return l.layout;
});
return {stackedChildren, crossSize};

View File

@@ -14,6 +14,7 @@
#import "ASLayoutSpecUtilities.h"
#import "ASStackLayoutSpecUtilities.h"
#import "ASLayoutOptions.h"
/**
Sizes the child given the parameters specified, and returns the computed layout.
@@ -25,8 +26,7 @@ static ASLayout *crossChildLayout(const id<ASLayoutable> child,
const CGFloat crossMin,
const CGFloat crossMax)
{
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:child];
const ASStackLayoutAlignItems alignItems = alignment(layoutOptions.alignSelf, style.alignItems);
const ASStackLayoutAlignItems alignItems = alignment(child.layoutOptions.alignSelf, style.alignItems);
// stretched children will have a cross dimension of at least crossMin
const CGFloat childCrossMin = alignItems == ASStackLayoutAlignItemsStretch ? crossMin : 0;
const ASSizeRange childSizeRange = directionSizeRange(style.direction, stackMin, stackMax, childCrossMin, crossMax);
@@ -76,8 +76,7 @@ static void stretchChildrenAlongCrossDimension(std::vector<ASStackUnpositionedIt
const CGFloat childCrossMax = it == layouts.end() ? 0 : crossDimension(style.direction, it->layout.size);
for (auto &l : layouts) {
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:l.child];
const ASStackLayoutAlignItems alignItems = alignment(layoutOptions.alignSelf, style.alignItems);
const ASStackLayoutAlignItems alignItems = alignment(l.child.layoutOptions.alignSelf, style.alignItems);
const CGFloat cross = crossDimension(style.direction, l.layout.size);
const CGFloat stack = stackDimension(style.direction, l.layout.size);
@@ -113,8 +112,7 @@ static CGFloat computeStackDimensionSum(const std::vector<ASStackUnpositionedIte
// Start from default spacing between each child:
children.empty() ? 0 : style.spacing * (children.size() - 1),
[&](CGFloat x, const ASStackUnpositionedItem &l) {
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:l.child];
return x + layoutOptions.spacingBefore + layoutOptions.spacingAfter;
return x + l.child.layoutOptions.spacingBefore + l.child.layoutOptions.spacingAfter;
});
// Sum up the childrens' dimensions (including spacing) in the stack direction.
@@ -183,16 +181,15 @@ static std::function<BOOL(const ASStackUnpositionedItem &)> isFlexibleInViolatio
if (fabs(violation) < kViolationEpsilon) {
return [](const ASStackUnpositionedItem &l) { return NO; };
} else if (violation > 0) {
return [](const ASStackUnpositionedItem &l) { return [ASLayoutSpec layoutOptionsForChild:l.child].flexGrow; };
return [](const ASStackUnpositionedItem &l) { return l.child.layoutOptions.flexGrow; };
} else {
return [](const ASStackUnpositionedItem &l) { return [ASLayoutSpec layoutOptionsForChild:l.child].flexShrink; };
return [](const ASStackUnpositionedItem &l) { return l.child.layoutOptions.flexShrink; };
}
}
ASDISPLAYNODE_INLINE BOOL isFlexibleInBothDirections(id<ASLayoutable> child)
{
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:child];
return layoutOptions.flexGrow && layoutOptions.flexShrink;
return child.layoutOptions.flexGrow && child.layoutOptions.flexShrink;
}
/**
@@ -297,9 +294,8 @@ static std::vector<ASStackUnpositionedItem> layoutChildrenAlongUnconstrainedStac
const CGFloat maxCrossDimension = crossDimension(style.direction, sizeRange.max);
return AS::map(children, [&](id<ASLayoutable> child) -> ASStackUnpositionedItem {
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:child];
const BOOL isUnconstrainedFlexBasis = ASRelativeDimensionEqualToRelativeDimension(ASRelativeDimensionUnconstrained, layoutOptions.flexBasis);
const CGFloat exactStackDimension = ASRelativeDimensionResolve(layoutOptions.flexBasis, stackDimension(style.direction, size));
const BOOL isUnconstrainedFlexBasis = ASRelativeDimensionEqualToRelativeDimension(ASRelativeDimensionUnconstrained, child.layoutOptions.flexBasis);
const CGFloat exactStackDimension = ASRelativeDimensionResolve(child.layoutOptions.flexBasis, stackDimension(style.direction, size));
if (useOptimizedFlexing && isFlexibleInBothDirections(child)) {
return { child, [ASLayout layoutWithLayoutableObject:child size:{0, 0}] };

View File

@@ -13,6 +13,7 @@
#import "ASBackgroundLayoutSpec.h"
#import "ASCenterLayoutSpec.h"
#import "ASStackLayoutSpec.h"
#import "ASLayoutOptions.h"
static const ASSizeRange kSize = {{100, 120}, {320, 160}};
@@ -94,7 +95,7 @@ static NSString *suffixForCenteringOptions(ASCenterLayoutSpecCenteringOptions ce
ASDisplayNode *backgroundNode = ASDisplayNodeWithBackgroundColor([UIColor redColor]);
ASStaticSizeDisplayNode *foregroundNode = ASDisplayNodeWithBackgroundColor([UIColor redColor]);
foregroundNode.staticSize = {10, 10};
[ASLayoutSpec layoutOptionsForChild:foregroundNode].flexGrow = YES;
foregroundNode.layoutOptions.flexGrow = YES;
ASCenterLayoutSpec *layoutSpec =
[ASCenterLayoutSpec

View File

@@ -15,6 +15,7 @@
#import "ASBackgroundLayoutSpec.h"
#import "ASRatioLayoutSpec.h"
#import "ASInsetLayoutSpec.h"
#import "ASLayoutOptions.h"
@interface ASStackLayoutSpecSnapshotTests : ASLayoutSpecSnapshotTestCase
@end
@@ -41,8 +42,8 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
];
for (ASStaticSizeDisplayNode *subnode in subnodes) {
subnode.staticSize = subnodeSize;
[ASLayoutSpec layoutOptionsForChild:subnode].flexGrow = flex;
[ASLayoutSpec layoutOptionsForChild:subnode].flexShrink = flex;
subnode.layoutOptions.flexGrow = flex;
subnode.layoutOptions.flexShrink = flex;
}
return subnodes;
}
@@ -114,7 +115,7 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
ASStackLayoutSpecStyle style = {.direction = ASStackLayoutDirectionHorizontal};
NSArray *subnodes = defaultSubnodesWithSameSize({50, 50}, NO);
[ASLayoutSpec layoutOptionsForChild:((ASDisplayNode *)subnodes[1])].flexShrink = YES;
((ASDisplayNode *)subnodes[1]).layoutOptions.flexShrink = YES;
// Width is 75px--that's less than the sum of the widths of the children, which is 100px.
static ASSizeRange kSize = {{75, 0}, {75, 150}};
@@ -204,25 +205,23 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
ASLayoutOptions *layoutOptions1 = [ASLayoutSpec layoutOptionsForChild:subnodes[1]];
ASLayoutOptions *layoutOptions2 = [ASLayoutSpec layoutOptionsForChild:subnodes[2]];
layoutOptions1.spacingBefore = 10;
layoutOptions2.spacingBefore = 20;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.spacingBefore = 10;
((ASStaticSizeDisplayNode *)subnodes[2]).layoutOptions.spacingBefore = 20;
[self testStackLayoutSpecWithStyle:style sizeRange:kAnySize subnodes:subnodes identifier:@"spacingBefore"];
// Reset above spacing values
layoutOptions1.spacingBefore = 0;
layoutOptions2.spacingBefore = 0;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.spacingBefore = 0;
((ASStaticSizeDisplayNode *)subnodes[2]).layoutOptions.spacingBefore = 0;
layoutOptions1.spacingAfter = 10;
layoutOptions2.spacingAfter = 20;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.spacingAfter = 10;
((ASStaticSizeDisplayNode *)subnodes[2]).layoutOptions.spacingAfter = 20;
[self testStackLayoutSpecWithStyle:style sizeRange:kAnySize subnodes:subnodes identifier:@"spacingAfter"];
// Reset above spacing values
layoutOptions1.spacingAfter = 0;
layoutOptions2.spacingAfter = 0;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.spacingAfter = 0;
((ASStaticSizeDisplayNode *)subnodes[2]).layoutOptions.spacingAfter = 0;
style.spacing = 10;
layoutOptions1.spacingBefore = -10;
layoutOptions2.spacingAfter = -10;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.spacingBefore = -10;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.spacingAfter = -10;
[self testStackLayoutSpecWithStyle:style sizeRange:kAnySize subnodes:subnodes identifier:@"spacingBalancedOut"];
}
@@ -238,9 +237,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].spacingBefore = 0;
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].spacingBefore = 20;
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].spacingBefore = 30;
((ASStaticSizeDisplayNode *)subnodes[0]).layoutOptions.spacingBefore = 0;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.spacingBefore = 20;
((ASStaticSizeDisplayNode *)subnodes[2]).layoutOptions.spacingBefore = 30;
// width 0-300px; height 300px
static ASSizeRange kVariableHeight = {{0, 300}, {300, 300}};
@@ -256,10 +255,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
subnode2.staticSize = {50, 50};
ASRatioLayoutSpec *child1 = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:1.5 child:subnode1];
ASLayoutOptions *layoutOptions1 = [ASLayoutSpec layoutOptionsForChild:child1];
layoutOptions1.flexBasis = ASRelativeDimensionMakeWithPercent(1);
layoutOptions1.flexGrow = YES;
layoutOptions1.flexShrink = YES;
child1.layoutOptions.flexBasis = ASRelativeDimensionMakeWithPercent(1);
child1.layoutOptions.flexGrow = YES;
child1.layoutOptions.flexShrink = YES;
static ASSizeRange kFixedWidth = {{150, 0}, {150, INFINITY}};
[self testStackLayoutSpecWithStyle:style children:@[child1, subnode2] sizeRange:kFixedWidth subnodes:@[subnode1, subnode2] identifier:nil];
@@ -274,11 +272,11 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
ASStaticSizeDisplayNode *subnode1 = ASDisplayNodeWithBackgroundColor([UIColor redColor]);
subnode1.staticSize = {100, 100};
[ASLayoutSpec layoutOptionsForChild:subnode1].flexShrink = YES;
subnode1.layoutOptions.flexShrink = YES;
ASStaticSizeDisplayNode *subnode2 = ASDisplayNodeWithBackgroundColor([UIColor blueColor]);
subnode2.staticSize = {50, 50};
[ASLayoutSpec layoutOptionsForChild:subnode2].flexShrink = YES;
subnode2.layoutOptions.flexShrink = YES;
NSArray *subnodes = @[subnode1, subnode2];
static ASSizeRange kFixedWidth = {{150, 0}, {150, 100}};
@@ -294,7 +292,7 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
ASStaticSizeDisplayNode *subnode2 = ASDisplayNodeWithBackgroundColor([UIColor blueColor]);
subnode2.staticSize = {50, 50};
[ASLayoutSpec layoutOptionsForChild:subnode2].alignSelf = ASStackLayoutAlignSelfCenter;
subnode2.layoutOptions.alignSelf = ASStackLayoutAlignSelfCenter;
NSArray *subnodes = @[subnode1, subnode2];
static ASSizeRange kFixedWidth = {{150, 0}, {150, INFINITY}};
@@ -314,9 +312,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].spacingBefore = 0;
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].spacingBefore = 20;
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].spacingBefore = 30;
((ASStaticSizeDisplayNode *)subnodes[0]).layoutOptions.spacingBefore = 0;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.spacingBefore = 20;
((ASStaticSizeDisplayNode *)subnodes[2]).layoutOptions.spacingBefore = 30;
static ASSizeRange kExactSize = {{300, 300}, {300, 300}};
[self testStackLayoutSpecWithStyle:style sizeRange:kExactSize subnodes:subnodes identifier:nil];
@@ -335,9 +333,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].spacingBefore = 0;
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].spacingBefore = 20;
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].spacingBefore = 30;
((ASStaticSizeDisplayNode *)subnodes[0]).layoutOptions.spacingBefore = 0;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.spacingBefore = 20;
((ASStaticSizeDisplayNode *)subnodes[2]).layoutOptions.spacingBefore = 30;
static ASSizeRange kExactSize = {{300, 300}, {300, 300}};
[self testStackLayoutSpecWithStyle:style sizeRange:kExactSize subnodes:subnodes identifier:nil];
@@ -356,9 +354,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].spacingBefore = 0;
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].spacingBefore = 20;
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].spacingBefore = 30;
((ASStaticSizeDisplayNode *)subnodes[0]).layoutOptions.spacingBefore = 0;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.spacingBefore = 20;
((ASStaticSizeDisplayNode *)subnodes[2]).layoutOptions.spacingBefore = 30;
static ASSizeRange kExactSize = {{300, 300}, {300, 300}};
[self testStackLayoutSpecWithStyle:style sizeRange:kExactSize subnodes:subnodes identifier:nil];
@@ -377,9 +375,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].spacingBefore = 0;
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].spacingBefore = 20;
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].spacingBefore = 30;
((ASStaticSizeDisplayNode *)subnodes[0]).layoutOptions.spacingBefore = 0;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.spacingBefore = 20;
((ASStaticSizeDisplayNode *)subnodes[2]).layoutOptions.spacingBefore = 30;
static ASSizeRange kVariableSize = {{200, 200}, {300, 300}};
// all children should be 200px wide
@@ -399,9 +397,9 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 70};
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {150, 90};
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].spacingBefore = 0;
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].spacingBefore = 20;
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].spacingBefore = 30;
((ASStaticSizeDisplayNode *)subnodes[0]).layoutOptions.spacingBefore = 0;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.spacingBefore = 20;
((ASStaticSizeDisplayNode *)subnodes[2]).layoutOptions.spacingBefore = 30;
static ASSizeRange kVariableSize = {{50, 50}, {300, 300}};
// all children should be 150px wide
@@ -422,9 +420,8 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {150, 150};
for (ASStaticSizeDisplayNode *subnode in subnodes) {
ASLayoutOptions *layoutOptions = [ASLayoutSpec layoutOptionsForChild:subnode];
layoutOptions.flexGrow = YES;
layoutOptions.flexBasis = ASRelativeDimensionMakeWithPoints(10);
subnode.layoutOptions.flexGrow = YES;
subnode.layoutOptions.flexBasis = ASRelativeDimensionMakeWithPoints(10);
}
// width 300px; height 0-150px.
@@ -443,12 +440,12 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
NSArray *subnodes = defaultSubnodesWithSameSize({50, 50}, NO);
for (ASStaticSizeDisplayNode *subnode in subnodes) {
[ASLayoutSpec layoutOptionsForChild:subnode].flexGrow = YES;
subnode.layoutOptions.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.
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].flexBasis = ASRelativeDimensionMakeWithPercent(0.5);
((ASStaticSizeDisplayNode *)subnodes[0]).layoutOptions.flexBasis = ASRelativeDimensionMakeWithPercent(0.5);
static ASSizeRange kSize = {{200, 0}, {200, INFINITY}};
[self testStackLayoutSpecWithStyle:style sizeRange:kSize subnodes:subnodes identifier:nil];
@@ -464,7 +461,7 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {50, 50};
for (ASStaticSizeDisplayNode *subnode in subnodes) {
[ASLayoutSpec layoutOptionsForChild:subnode].flexBasis = ASRelativeDimensionMakeWithPoints(20);
subnode.layoutOptions.flexBasis = ASRelativeDimensionMakeWithPoints(20);
}
static ASSizeRange kSize = {{300, 0}, {300, 150}};
@@ -482,9 +479,8 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {3000, 3000};
ASRatioLayoutSpec *child2 = [ASRatioLayoutSpec ratioLayoutSpecWithRatio:1.0 child:subnodes[2]];
ASLayoutOptions *layoutOptions2 = [ASLayoutSpec layoutOptionsForChild:child2];
layoutOptions2.flexGrow = YES;
layoutOptions2.flexShrink = YES;
child2.layoutOptions.flexGrow = YES;
child2.layoutOptions.flexShrink = YES;
// If cross axis stretching occurred *before* flexing, then the blue child would be stretched to 3000 points tall.
// Instead it should be stretched to 300 points tall, matching the red child and not overlapping the green inset.
@@ -509,13 +505,13 @@ static NSArray *defaultSubnodesWithSameSize(CGSize subnodeSize, BOOL flex)
NSArray *subnodes = defaultSubnodes();
((ASStaticSizeDisplayNode *)subnodes[0]).staticSize = {300, 50};
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[0])].flexShrink = YES;
((ASStaticSizeDisplayNode *)subnodes[0]).layoutOptions.flexShrink = YES;
((ASStaticSizeDisplayNode *)subnodes[1]).staticSize = {100, 50};
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[1])].flexShrink = NO;
((ASStaticSizeDisplayNode *)subnodes[1]).layoutOptions.flexShrink = NO;
((ASStaticSizeDisplayNode *)subnodes[2]).staticSize = {200, 50};
[ASLayoutSpec layoutOptionsForChild:((ASStaticSizeDisplayNode *)subnodes[2])].flexShrink = YES;
((ASStaticSizeDisplayNode *)subnodes[2]).layoutOptions.flexShrink = YES;
// A width of 400px results in a violation of 200px. This is distributed equally among each flexible child,
// causing both of them to be shrunk by 100px, resulting in widths of 300px, 100px, and 50px.

View File

@@ -136,7 +136,6 @@ static const CGFloat kInnerPadding = 10.0f;
{
_imageNode.preferredFrameSize = _isImageEnlarged ? CGSizeMake(2.0 * kImageSize, 2.0 * kImageSize) : CGSizeMake(kImageSize, kImageSize);
_textNode.flexShrink = YES;
_textNode.flexGrow = YES;
ASStackLayoutSpec *stackSpec = [[ASStackLayoutSpec alloc] init];
stackSpec.direction = ASStackLayoutDirectionHorizontal;