mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-09-06 12:43:58 +00:00
160 lines
5.7 KiB
Objective-C
160 lines
5.7 KiB
Objective-C
//
|
|
// SampleSizingNode.m
|
|
// Sample
|
|
//
|
|
// Created by Michael Schneider on 11/10/16.
|
|
// Copyright © 2016 AsyncDisplayKit. All rights reserved.
|
|
//
|
|
|
|
#import "SampleSizingNode.h"
|
|
|
|
@interface SampleSizingNodeSubnode : ASDisplayNode
|
|
@property (strong, nonatomic) ASTextNode *textNode;
|
|
@end
|
|
|
|
@implementation SampleSizingNodeSubnode
|
|
|
|
- (void)layout
|
|
{
|
|
[super layout];
|
|
|
|
// Manual layout after the normal layout engine did it's job
|
|
// Calculated size can be used after the layout spec pass happened
|
|
//self.textNode.frame = CGRectMake(self.textNode.frame.origin.x, self.textNode.frame.origin.y, self.textNode.calculatedSize.width, 20);
|
|
}
|
|
|
|
@end
|
|
|
|
@interface SampleSizingNode ()
|
|
@property (nonatomic, assign) NSInteger state;
|
|
|
|
@property (nonatomic, strong) SampleSizingNodeSubnode *subnode;
|
|
@property (nonatomic, strong) ASTextNode *textNode;
|
|
@property (nonatomic, strong) ASNetworkImageNode *imageNode;
|
|
@end
|
|
|
|
@implementation SampleSizingNode
|
|
|
|
- (instancetype)init
|
|
{
|
|
self = [super init];
|
|
if (self) {
|
|
|
|
self.automaticallyManagesSubnodes = YES;
|
|
|
|
self.backgroundColor = [UIColor greenColor];
|
|
|
|
_textNode = [ASTextNode new];
|
|
_textNode.backgroundColor = [UIColor blueColor];
|
|
|
|
_imageNode = [ASNetworkImageNode new];
|
|
_imageNode.URL = [NSURL URLWithString:@"https://upload.wikimedia.org/wikipedia/commons/thumb/8/82/Mont_Blanc_oct_2004.JPG/280px-Mont_Blanc_oct_2004.JPG"];
|
|
_imageNode.backgroundColor = [UIColor brownColor];
|
|
_imageNode.needsDisplayOnBoundsChange = YES;
|
|
_imageNode.style.height = ASDimensionMakeWithFraction(1.0);
|
|
_imageNode.style.width = ASDimensionMake(50.0);
|
|
|
|
|
|
_subnode = [SampleSizingNodeSubnode new];
|
|
_subnode.textNode = _textNode;
|
|
_subnode.backgroundColor = [UIColor redColor];
|
|
_subnode.automaticallyManagesSubnodes = YES;
|
|
|
|
// Layout description via layoutSpecBlock
|
|
__weak __typeof(self) weakSelf = self;
|
|
_subnode.layoutSpecBlock = ^ASLayoutSpec *(__kindof ASDisplayNode * _Nonnull node, ASSizeRange constrainedSize) {
|
|
|
|
UIEdgeInsets insets = UIEdgeInsetsMake(10, 10, 10, 10);
|
|
ASInsetLayoutSpec *textInsetSpec = [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:weakSelf.textNode];
|
|
textInsetSpec.style.flexShrink = 1.0;
|
|
|
|
return [ASStackLayoutSpec
|
|
stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal
|
|
spacing:0.0
|
|
justifyContent:ASStackLayoutJustifyContentStart
|
|
alignItems:ASStackLayoutAlignItemsStart
|
|
children:@[weakSelf.imageNode, textInsetSpec]];
|
|
//return [ASAbsoluteLayoutSpec absoluteLayoutSpecWithSizing:ASAbsoluteLayoutSpecSizingSizeToFit children:@[_imageNode, insetSpec]];
|
|
};
|
|
|
|
_state = 0;
|
|
}
|
|
return self;
|
|
}
|
|
|
|
- (void)didLoad
|
|
{
|
|
[super didLoad];
|
|
|
|
|
|
// Initial state
|
|
self.state = 0;
|
|
|
|
// Simulate a state change of the node
|
|
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
|
self.state = 1;
|
|
});
|
|
}
|
|
|
|
#pragma mark - State Management
|
|
|
|
- (void)setState:(NSInteger)state
|
|
{
|
|
_state = state;
|
|
|
|
// Set text based on state
|
|
NSString *text = state == 0 ? @"Bla Bla" : @"Bla Blaa sd fkj as;l dkf";
|
|
self.textNode.attributedText = [[NSAttributedString alloc] initWithString:text];
|
|
|
|
//self.imageNode.style.width = state == 0 ? ASDimensionMake(30.0) : ASDimensionMake(50.0);
|
|
|
|
// Let the root node know there can be a size change happened. If we will not call this the text node will just
|
|
// use it's own bounds and layout again in the next layout pass what can result in truncation
|
|
[self invalidateCalculatedLayoutSizingBlaBla];
|
|
}
|
|
|
|
// Invalidates the current layout and bubbles up the setNeedsLayout call to the root node. The root node will inform
|
|
// the sizing delegate that a size change did happen and it's up to it to decide if the bounds of the root node should
|
|
// change based on this request or not. If no change happened the layout will happen in all subnodes based on the current
|
|
// set bounds
|
|
- (void)invalidateCalculatedLayoutSizingBlaBla
|
|
{
|
|
// Invalidate the layout for now and bubble it up until the root node to let the size provider know that
|
|
// that a size change could have happened
|
|
// --> Do we even need to invalidate the layout?
|
|
[self setNeedsLayout];
|
|
|
|
// If someone calls `invalidateBlaBla TBD` we have to inform the sizing delegate of the root node to be able
|
|
// to let them now that a size change happened and it needs to calculate a new layout / size for this node hierarchy
|
|
/*if ([self.sizingDelegate respondsToSelector:@selector(displayNodeDidInvalidateSize:)]) {
|
|
[self.sizingDelegate performSelector:@selector(displayNodeDidInvalidateSize:) withObject:self];
|
|
}*/
|
|
[self invalidateSize];
|
|
}
|
|
|
|
#pragma mark - ASDisplayNode
|
|
|
|
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
|
{
|
|
// Layout description based on state
|
|
// UIEdgeInsets insets = UIEdgeInsetsMake(10, 10, 10, 10);
|
|
// return [ASInsetLayoutSpec insetLayoutSpecWithInsets:insets child:_textNode];
|
|
|
|
//return [ASWrapperLayoutSpec wrapperWithLayoutElement:self.subnode];
|
|
return [ASCenterLayoutSpec
|
|
centerLayoutSpecWithCenteringOptions:ASCenterLayoutSpecCenteringXY
|
|
sizingOptions:ASCenterLayoutSpecSizingOptionDefault
|
|
child:self.subnode];
|
|
}
|
|
|
|
- (void)layout
|
|
{
|
|
[super layout];
|
|
|
|
// Layout after the official layout pass happened
|
|
//self.subnode.frame = CGRectMake(self.subnode.frame.origin.x, self.subnode.frame.origin.y, 100, self.calculatedSize.height);
|
|
}
|
|
|
|
|
|
@end
|