[ASEnvironment - Layout] Fixes to upward propagation of ASLayoutable properties.

This commit is contained in:
Hannah Troisi 2016-04-02 15:03:43 -07:00
parent a817abd43f
commit dbad1c38e5
12 changed files with 54 additions and 67 deletions

View File

@ -1702,10 +1702,6 @@ static NSInteger incrementIfFound(NSInteger i) {
[self exitHierarchyState:stateToEnterOrExit];
}
}
if ([newSupernode supportsUpwardPropagation]) {
ASEnvironmentStatePropagateUp(newSupernode, _environmentState.layoutOptionsState);
}
}
// Track that a node will be displayed as part of the current node hierarchy.
@ -1860,7 +1856,7 @@ void recursivelyTriggerDisplayForLayer(CALayer *layer, BOOL shouldBlock)
ASDN::MutexLocker l(_propertyLock);
if (_methodOverrides & ASDisplayNodeMethodOverrideLayoutSpecThatFits) {
ASLayoutSpec *layoutSpec = [self layoutSpecThatFits:constrainedSize];
layoutSpec.parent = self;
layoutSpec.parent = self; // This causes upward propogation of any non-default layoutable values.
layoutSpec.isMutable = NO;
ASLayout *layout = [layoutSpec measureWithSizeRange:constrainedSize];
// Make sure layoutableObject of the root layout is `self`, so that the flattened layout will be structurally correct.

View File

@ -81,8 +81,8 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
id<ASLayoutable> finalLayoutable = [child finalLayoutable];
if (finalLayoutable != child) {
// Layout options state of child needs to be copied to final layoutable
finalLayoutable.environmentState.layoutOptionsState = child.environmentState.layoutOptionsState;
// Layout options state of child needs to be copied to final layoutable, but don't override customized values.
ASEnvironmentStatePropagateUp(finalLayoutable, child.environmentState.layoutOptionsState);
return finalLayoutable;
}
}
@ -99,10 +99,11 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
- (void)setParent:(id<ASLayoutable>)parent
{
// FIXME: Locking should be evaluated here. _parent is not widely used yet, though.
_parent = parent;
if ([parent supportsUpwardPropagation]) {
ASEnvironmentStatePropagateUp(parent, _environmentState.layoutOptionsState);
ASEnvironmentStatePropagateUp(parent, self.environmentState.layoutOptionsState);
}
}
@ -115,12 +116,11 @@ static NSString * const kDefaultChildrenKey = @"kDefaultChildrenKey";
{
ASDisplayNodeAssert(self.isMutable, @"Cannot set properties when layout spec is not mutable");
id<ASLayoutable> finalLayoutable = [self layoutableToAddFromLayoutable:child];
BOOL needsToPropagateLayoutOptionsState = (child != finalLayoutable);
self.layoutChildren[identifier] = finalLayoutable;
if (needsToPropagateLayoutOptionsState) {
// We only need to propagate up layout options in setChild: as up propagation is currently only supported for
// layout specification has with one child
[self propagateUpLayoutOptionsState];
if ([finalLayoutable isKindOfClass:[ASLayoutSpec class]]) {
[(ASLayoutSpec *)finalLayoutable setParent:self]; // This will trigger upward propogation if needed.
} else if ([self supportsUpwardPropagation]) {
ASEnvironmentStatePropagateUp(self, finalLayoutable.environmentState.layoutOptionsState); // Probably an ASDisplayNode
}
}

View File

@ -115,33 +115,33 @@ ASEnvironmentState ASEnvironmentMergeObjectAndState(ASEnvironmentState environme
// For every field check if the parent value is equal to the default than propegate up the child value to
// the parent
if (parentState.spacingBefore != defaultState.spacingBefore) {
if (parentState.spacingBefore == defaultState.spacingBefore) {
parentState.spacingBefore = state.spacingBefore;
}
if (parentState.spacingAfter != defaultState.spacingAfter) {
if (parentState.spacingAfter == defaultState.spacingAfter) {
parentState.spacingAfter = state.spacingAfter;
}
if (parentState.alignSelf != defaultState.alignSelf) {
parentState.alignSelf = defaultState.alignSelf;
if (parentState.alignSelf == defaultState.alignSelf) {
parentState.alignSelf = state.alignSelf;
}
if (parentState.flexGrow != defaultState.flexGrow) {
parentState.flexGrow = defaultState.flexGrow;
if (parentState.flexGrow == defaultState.flexGrow) {
parentState.flexGrow = state.flexGrow;
}
if (!ASRelativeDimensionEqualToRelativeDimension(parentState.flexBasis, defaultState.flexBasis)) {
parentState.flexBasis = defaultState.flexBasis;
if (ASRelativeDimensionEqualToRelativeDimension(parentState.flexBasis, defaultState.flexBasis)) {
parentState.flexBasis = state.flexBasis;
}
if (parentState.alignSelf != defaultState.alignSelf) {
parentState.alignSelf = defaultState.alignSelf;
if (parentState.alignSelf == defaultState.alignSelf) {
parentState.alignSelf = state.alignSelf;
}
if (parentState.ascender != defaultState.ascender) {
parentState.ascender = defaultState.ascender;
if (parentState.ascender == defaultState.ascender) {
parentState.ascender = state.ascender;
}
if (!ASRelativeSizeRangeEqualToRelativeSizeRange(parentState.sizeRange, defaultState.sizeRange)) {
parentState.sizeRange = defaultState.sizeRange;
if (ASRelativeSizeRangeEqualToRelativeSizeRange(parentState.sizeRange, defaultState.sizeRange)) {
parentState.sizeRange = state.sizeRange;
}
if (CGPointEqualToPoint(parentState.layoutPosition, defaultState.layoutPosition)) {
parentState.layoutPosition = defaultState.layoutPosition;
parentState.layoutPosition = state.layoutPosition;
}
environmentState.layoutOptionsState = parentState;

View File

@ -15,6 +15,4 @@
@property (strong, nonatomic) UIWindow *window;
@end

View File

@ -10,23 +10,17 @@
*/
#import "AppDelegate.h"
#import "ViewController.h"
@interface AppDelegate ()
@end
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
self.window.backgroundColor = [UIColor whiteColor];
self.window.rootViewController = [[UINavigationController alloc] initWithRootViewController:[[ViewController alloc] init]];
[self.window makeKeyAndVisible];
return YES;
}
@end

View File

@ -20,8 +20,8 @@
@implementation CommentsNode
- (instancetype)initWithCommentsCount:(NSInteger)comentsCount {
- (instancetype)initWithCommentsCount:(NSInteger)comentsCount
{
self = [super init];
if (self) {
_commentsCount = comentsCount;
@ -44,8 +44,8 @@
}
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize {
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
ASStackLayoutSpec *mainStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:6.0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsCenter children:@[self.iconNode, self.countNode]];
// set sizeRange to make width fixed to 60
@ -55,5 +55,4 @@
return [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[mainStack]];
}
@end

View File

@ -21,8 +21,8 @@
@implementation LikesNode
- (instancetype)initWithLikesCount:(NSInteger)likesCount {
- (instancetype)initWithLikesCount:(NSInteger)likesCount
{
self = [super init];
if (self) {
_likesCount = likesCount;
@ -49,7 +49,7 @@
}
+ (BOOL) getYesOrNo
+ (BOOL)getYesOrNo
{
int tmp = (arc4random() % 30)+1;
if (tmp % 5 == 0) {
@ -58,8 +58,8 @@
return NO;
}
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize {
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
ASStackLayoutSpec *mainStack = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal spacing:6.0 justifyContent:ASStackLayoutJustifyContentStart alignItems:ASStackLayoutAlignItemsCenter children:@[_iconNode, _countNode]];
// set sizeRange to make width fixed to 60
@ -67,7 +67,6 @@
ASRelativeSize max = ASRelativeSizeMake(ASRelativeDimensionMakeWithPoints(60.0), ASRelativeDimensionMakeWithPoints(40.0));
mainStack.sizeRange = ASRelativeSizeRangeMake(min, max);
return [ASStaticLayoutSpec staticLayoutSpecWithChildren:@[mainStack]];
}
@end

View File

@ -12,5 +12,4 @@
#import "Post.h"
@implementation Post
@end

View File

@ -34,8 +34,8 @@
@implementation PostNode
- (instancetype)initWithPost:(Post *)post {
- (instancetype)initWithPost:(Post *)post
{
self = [super init];
if (self) {
_post = post;
@ -181,14 +181,19 @@
[super didLoad];
}
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize {
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
// Flexible spacer between username and time
ASLayoutSpec *spacer = [[ASLayoutSpec alloc] init];
spacer.flexGrow = YES;
// NOTE: This inset is not actually required by the layout, but is an example of the upward propogation of layoutable
// properties. Specifically, .flexGrow from the child is transferred to the inset spec so they can expand together.
// Without this capability, it would be required to set insetSpacer.flexGrow = YES;
ASInsetLayoutSpec *insetSpacer = [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsMake(0, 0, 0, 0) child:spacer];
// Horizontal stack for name, username, via icon and time
NSMutableArray *layoutSpecChildren = [@[_nameNode, _usernameNode, spacer] mutableCopy];
NSMutableArray *layoutSpecChildren = [@[_nameNode, _usernameNode, insetSpacer] mutableCopy];
if (_post.via != 0) {
[layoutSpecChildren addObject:_viaNode];
}

View File

@ -54,16 +54,16 @@
};
}
+ (NSDictionary *)cellControlStyle {
+ (NSDictionary *)cellControlStyle
{
return @{
NSFontAttributeName : [UIFont systemFontOfSize:13.0],
NSForegroundColorAttributeName: [UIColor lightGrayColor]
};
}
+ (NSDictionary *)cellControlColoredStyle {
+ (NSDictionary *)cellControlColoredStyle
{
return @{
NSFontAttributeName : [UIFont systemFontOfSize:13.0],
NSForegroundColorAttributeName: [UIColor colorWithRed:59.0/255.0 green:89.0/255.0 blue:152.0/255.0 alpha:1.0]

View File

@ -12,7 +12,4 @@
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
@end

View File

@ -45,8 +45,8 @@
_tableView.asyncDelegate = nil;
}
- (void)viewDidLoad {
- (void)viewDidLoad
{
[super viewDidLoad];
self.tableView = [[ASTableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain asyncDataFetching:YES];
@ -57,8 +57,8 @@
[self.view addSubview:self.tableView];
}
- (void)createSocialAppDataSource {
- (void)createSocialAppDataSource
{
_socialAppDataSource = [[NSMutableArray alloc] init];
Post *newPost = [[Post alloc] init];