Peter 9bc996374f Add 'submodules/AsyncDisplayKit/' from commit '02bedc12816e251ad71777f9d2578329b6d2bef6'
git-subtree-dir: submodules/AsyncDisplayKit
git-subtree-mainline: d06f423e0ed3df1fed9bd10d79ee312a9179b632
git-subtree-split: 02bedc12816e251ad71777f9d2578329b6d2bef6
2019-06-11 18:42:43 +01:00

188 lines
5.9 KiB
Objective-C

//
// ViewController.m
// Texture
//
// Copyright (c) Facebook, Inc. and its affiliates. All rights reserved.
// Changes after 4/13/2017 are: Copyright (c) Pinterest, Inc. All rights reserved.
// Licensed under Apache 2.0: http://www.apache.org/licenses/LICENSE-2.0
//
#import "ViewController.h"
#import <AsyncDisplayKit/AsyncDisplayKit.h>
#pragma mark - TransitionNode
#define USE_CUSTOM_LAYOUT_TRANSITION 0
@interface TransitionNode : ASDisplayNode
@property (nonatomic, assign) BOOL enabled;
@property (nonatomic, strong) ASButtonNode *buttonNode;
@property (nonatomic, strong) ASTextNode *textNodeOne;
@property (nonatomic, strong) ASTextNode *textNodeTwo;
@end
@implementation TransitionNode
#pragma mark - Lifecycle
- (instancetype)init
{
self = [super init];
if (self == nil) { return self; }
self.automaticallyManagesSubnodes = YES;
// Define the layout transition duration for the default transition
self.defaultLayoutTransitionDuration = 1.0;
_enabled = NO;
// Setup text nodes
_textNodeOne = [[ASTextNode alloc] init];
_textNodeOne.attributedText = [[NSAttributedString alloc] initWithString:@"Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled"];
_textNodeTwo = [[ASTextNode alloc] init];
_textNodeTwo.attributedText = [[NSAttributedString alloc] initWithString:@"It is a long established fact that a reader will be distracted by the readable content of a page when looking at its layout. The point of using Lorem Ipsum is that it has a more-or-less normal distribution of letters, as opposed to using 'Content here, content here', making it look like readable English."];
ASSetDebugNames(_textNodeOne, _textNodeTwo);
// Setup button
NSString *buttonTitle = @"Start Layout Transition";
UIFont *buttonFont = [UIFont systemFontOfSize:16.0];
UIColor *buttonColor = [UIColor blueColor];
_buttonNode = [[ASButtonNode alloc] init];
[_buttonNode setTitle:buttonTitle withFont:buttonFont withColor:buttonColor forState:UIControlStateNormal];
[_buttonNode setTitle:buttonTitle withFont:buttonFont withColor:[buttonColor colorWithAlphaComponent:0.5] forState:UIControlStateHighlighted];
// Some debug colors
_textNodeOne.backgroundColor = [UIColor orangeColor];
_textNodeTwo.backgroundColor = [UIColor greenColor];
return self;
}
- (void)didLoad
{
[super didLoad];
[self.buttonNode addTarget:self action:@selector(buttonPressed:) forControlEvents:ASControlNodeEventTouchUpInside];
}
#pragma mark - Actions
- (void)buttonPressed:(id)sender
{
self.enabled = !self.enabled;
[self transitionLayoutWithAnimation:YES shouldMeasureAsync:NO measurementCompletion:nil];
}
#pragma mark - Layout
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
{
ASTextNode *nextTextNode = self.enabled ? self.textNodeTwo : self.textNodeOne;
nextTextNode.style.flexGrow = 1.0;
nextTextNode.style.flexShrink = 1.0;
ASStackLayoutSpec *horizontalStackLayout = [ASStackLayoutSpec horizontalStackLayoutSpec];
horizontalStackLayout.children = @[nextTextNode];
self.buttonNode.style.alignSelf = ASStackLayoutAlignSelfCenter;
ASStackLayoutSpec *verticalStackLayout = [ASStackLayoutSpec verticalStackLayoutSpec];
verticalStackLayout.spacing = 10.0;
verticalStackLayout.children = @[horizontalStackLayout, self.buttonNode];
return [ASInsetLayoutSpec insetLayoutSpecWithInsets:UIEdgeInsetsMake(15.0, 15.0, 15.0, 15.0) child:verticalStackLayout];
}
#pragma mark - Transition
#if USE_CUSTOM_LAYOUT_TRANSITION
- (void)animateLayoutTransition:(id<ASContextTransitioning>)context
{
ASDisplayNode *fromNode = [[context removedSubnodes] objectAtIndex:0];
ASDisplayNode *toNode = [[context insertedSubnodes] objectAtIndex:0];
ASButtonNode *buttonNode = nil;
for (ASDisplayNode *node in [context subnodesForKey:ASTransitionContextToLayoutKey]) {
if ([node isKindOfClass:[ASButtonNode class]]) {
buttonNode = (ASButtonNode *)node;
break;
}
}
CGRect toNodeFrame = [context finalFrameForNode:toNode];
toNodeFrame.origin.x += (self.enabled ? toNodeFrame.size.width : -toNodeFrame.size.width);
toNode.frame = toNodeFrame;
toNode.alpha = 0.0;
CGRect fromNodeFrame = fromNode.frame;
fromNodeFrame.origin.x += (self.enabled ? -fromNodeFrame.size.width : fromNodeFrame.size.width);
// We will use the same transition duration as the default transition
[UIView animateWithDuration:self.defaultLayoutTransitionDuration animations:^{
toNode.frame = [context finalFrameForNode:toNode];
toNode.alpha = 1.0;
fromNode.frame = fromNodeFrame;
fromNode.alpha = 0.0;
// Update frame of self
CGSize fromSize = [context layoutForKey:ASTransitionContextFromLayoutKey].size;
CGSize toSize = [context layoutForKey:ASTransitionContextToLayoutKey].size;
BOOL isResized = (CGSizeEqualToSize(fromSize, toSize) == NO);
if (isResized == YES) {
CGPoint position = self.frame.origin;
self.frame = CGRectMake(position.x, position.y, toSize.width, toSize.height);
}
buttonNode.frame = [context finalFrameForNode:buttonNode];
} completion:^(BOOL finished) {
[context completeTransition:finished];
}];
}
#endif
@end
#pragma mark - ViewController
@interface ViewController ()
@property (nonatomic, strong) TransitionNode *transitionNode;
@end
@implementation ViewController
#pragma mark - UIViewController
- (void)viewDidLoad
{
[super viewDidLoad];
_transitionNode = [TransitionNode new];
[self.view addSubnode:_transitionNode];
// Some debug colors
_transitionNode.backgroundColor = [UIColor grayColor];
}
- (void)viewDidLayoutSubviews
{
[super viewDidLayoutSubviews];
CGSize size = [self.transitionNode layoutThatFits:ASSizeRangeMake(CGSizeZero, self.view.frame.size)].size;
self.transitionNode.frame = CGRectMake(0, 20, size.width, size.height);
}
@end