mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-24 07:05:35 +00:00
[ASPagerNode] New API tweaks. Support setting delegate + dataSource on ASCollectionNode and ASTableNode without triggering view creation.
This commit is contained in:
@@ -17,6 +17,9 @@
|
|||||||
- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout;
|
- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout;
|
||||||
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;
|
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;
|
||||||
|
|
||||||
|
@property (weak, nonatomic) id <ASCollectionDelegate> delegate;
|
||||||
|
@property (weak, nonatomic) id <ASCollectionDataSource> dataSource;
|
||||||
|
|
||||||
@property (nonatomic, readonly) ASCollectionView *view;
|
@property (nonatomic, readonly) ASCollectionView *view;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -9,7 +9,19 @@
|
|||||||
#import "ASCollectionNode.h"
|
#import "ASCollectionNode.h"
|
||||||
#import "ASDisplayNode+Subclasses.h"
|
#import "ASDisplayNode+Subclasses.h"
|
||||||
|
|
||||||
@interface ASCollectionView (Internal)
|
@interface _ASCollectionPendingState : NSObject
|
||||||
|
@property (weak, nonatomic) id <ASCollectionDelegate> delegate;
|
||||||
|
@property (weak, nonatomic) id <ASCollectionDataSource> dataSource;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation _ASCollectionPendingState
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface ASCollectionNode ()
|
||||||
|
@property (nonatomic) _ASCollectionPendingState *pendingState;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface ASCollectionView ()
|
||||||
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;
|
- (instancetype)_initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;
|
||||||
@end
|
@end
|
||||||
|
|
||||||
@@ -29,12 +41,59 @@
|
|||||||
|
|
||||||
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout
|
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout
|
||||||
{
|
{
|
||||||
if (self = [super initWithViewBlock:^UIView *{ return [[ASCollectionView alloc] _initWithFrame:frame collectionViewLayout:layout]; }]) {
|
ASDisplayNodeViewBlock collectionViewBlock = ^UIView *{
|
||||||
|
return [[ASCollectionView alloc] _initWithFrame:frame collectionViewLayout:layout];
|
||||||
|
};
|
||||||
|
|
||||||
|
if (self = [super initWithViewBlock:collectionViewBlock]) {
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)didLoad
|
||||||
|
{
|
||||||
|
[super didLoad];
|
||||||
|
|
||||||
|
if (_pendingState) {
|
||||||
|
_ASCollectionPendingState *pendingState = _pendingState;
|
||||||
|
self.pendingState = nil;
|
||||||
|
|
||||||
|
ASCollectionView *view = self.view;
|
||||||
|
view.asyncDelegate = pendingState.delegate;
|
||||||
|
view.asyncDataSource = pendingState.dataSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (_ASCollectionPendingState *)pendingState
|
||||||
|
{
|
||||||
|
if (!_pendingState && ![self isNodeLoaded]) {
|
||||||
|
self.pendingState = [[_ASCollectionPendingState alloc] init];
|
||||||
|
}
|
||||||
|
ASDisplayNodeAssert(![self isNodeLoaded] || !_pendingState, @"ASCollectionNode should not have a pendingState once it is loaded");
|
||||||
|
return _pendingState;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDelegate:(id <ASCollectionDelegate>)delegate
|
||||||
|
{
|
||||||
|
if ([self pendingState]) {
|
||||||
|
_pendingState.delegate = delegate;
|
||||||
|
} else {
|
||||||
|
ASDisplayNodeAssert([self isNodeLoaded], @"ASCollectionNode should be loaded if pendingState doesn't exist");
|
||||||
|
self.view.asyncDelegate = delegate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDataSource:(id <ASCollectionDataSource>)dataSource
|
||||||
|
{
|
||||||
|
if ([self pendingState]) {
|
||||||
|
_pendingState.dataSource = dataSource;
|
||||||
|
} else {
|
||||||
|
ASDisplayNodeAssert([self isNodeLoaded], @"ASCollectionNode should be loaded if pendingState doesn't exist");
|
||||||
|
self.view.asyncDataSource = dataSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (ASCollectionView *)view
|
- (ASCollectionView *)view
|
||||||
{
|
{
|
||||||
return (ASCollectionView *)[super view];
|
return (ASCollectionView *)[super view];
|
||||||
|
|||||||
@@ -286,6 +286,8 @@
|
|||||||
/**
|
/**
|
||||||
* This is a node-based UICollectionViewDataSource.
|
* This is a node-based UICollectionViewDataSource.
|
||||||
*/
|
*/
|
||||||
|
@protocol ASCollectionDataSource <ASCollectionViewDataSource>
|
||||||
|
@end
|
||||||
@protocol ASCollectionViewDataSource <ASCommonCollectionViewDataSource, NSObject>
|
@protocol ASCollectionViewDataSource <ASCommonCollectionViewDataSource, NSObject>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -347,6 +349,8 @@
|
|||||||
/**
|
/**
|
||||||
* This is a node-based UICollectionViewDelegate.
|
* This is a node-based UICollectionViewDelegate.
|
||||||
*/
|
*/
|
||||||
|
@protocol ASCollectionDelegate <ASCollectionViewDelegate>
|
||||||
|
@end
|
||||||
@protocol ASCollectionViewDelegate <ASCommonCollectionViewDelegate, NSObject>
|
@protocol ASCollectionViewDelegate <ASCommonCollectionViewDelegate, NSObject>
|
||||||
|
|
||||||
@optional
|
@optional
|
||||||
|
|||||||
@@ -12,7 +12,21 @@
|
|||||||
|
|
||||||
@interface ASPagerNode : ASCollectionNode
|
@interface ASPagerNode : ASCollectionNode
|
||||||
|
|
||||||
@property (weak, nonatomic) id<ASPagerNodeDataSource> dataSource;
|
// Configures a default horizontal, paging flow layout with 0 inter-item spacing.
|
||||||
|
- (instancetype)init;
|
||||||
|
|
||||||
|
// Initializer with custom-configured flow layout properties.
|
||||||
|
- (instancetype)initWithFlowLayout:(UICollectionViewFlowLayout *)flowLayout;
|
||||||
|
|
||||||
|
// The underlying ASCollectionView object.
|
||||||
|
- (ASCollectionView *)collectionView;
|
||||||
|
|
||||||
|
// Delegate is optional, and uses the same protocol as ASCollectionNode.
|
||||||
|
// This includes UIScrollViewDelegate as well as most methods from UICollectionViewDelegate, like willDisplay...
|
||||||
|
@property (weak, nonatomic) id <ASCollectionDelegate> delegate;
|
||||||
|
|
||||||
|
// Data Source is required, and uses a different protocol from ASCollectionNode.
|
||||||
|
@property (weak, nonatomic) id <ASPagerNodeDataSource> dataSource;
|
||||||
|
|
||||||
- (void)scrollToPageAtIndex:(NSInteger)index animated:(BOOL)animated;
|
- (void)scrollToPageAtIndex:(NSInteger)index animated:(BOOL)animated;
|
||||||
|
|
||||||
@@ -20,8 +34,10 @@
|
|||||||
|
|
||||||
@protocol ASPagerNodeDataSource <NSObject>
|
@protocol ASPagerNodeDataSource <NSObject>
|
||||||
|
|
||||||
|
// This method replaces -collectionView:numberOfItemsInSection:
|
||||||
- (NSInteger)numberOfPagesInPagerNode:(ASPagerNode *)pagerNode;
|
- (NSInteger)numberOfPagesInPagerNode:(ASPagerNode *)pagerNode;
|
||||||
|
|
||||||
|
// This method replaces -collectionView:nodeForItemAtIndexPath:
|
||||||
- (ASCellNode *)pagerNode:(ASPagerNode *)pagerNode nodeAtIndex:(NSInteger)index;
|
- (ASCellNode *)pagerNode:(ASPagerNode *)pagerNode nodeAtIndex:(NSInteger)index;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -7,11 +7,14 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
#import "ASPagerNode.h"
|
#import "ASPagerNode.h"
|
||||||
|
#import "ASDelegateProxy.h"
|
||||||
|
|
||||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||||
|
|
||||||
@interface ASPagerNode () <ASCollectionViewDataSource, ASCollectionViewDelegateFlowLayout> {
|
@interface ASPagerNode () <ASCollectionViewDataSource, ASCollectionViewDelegateFlowLayout> {
|
||||||
UICollectionViewFlowLayout *_flowLayout;
|
UICollectionViewFlowLayout *_flowLayout;
|
||||||
|
ASPagerNodeProxy *_proxy;
|
||||||
|
id <ASPagerNodeDataSource> _pagerDataSource;
|
||||||
}
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
@@ -25,6 +28,11 @@
|
|||||||
flowLayout.minimumInteritemSpacing = 0;
|
flowLayout.minimumInteritemSpacing = 0;
|
||||||
flowLayout.minimumLineSpacing = 0;
|
flowLayout.minimumLineSpacing = 0;
|
||||||
|
|
||||||
|
return [self initWithFlowLayout:flowLayout];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (instancetype)initWithFlowLayout:(UICollectionViewFlowLayout *)flowLayout
|
||||||
|
{
|
||||||
self = [super initWithCollectionViewLayout:flowLayout];
|
self = [super initWithCollectionViewLayout:flowLayout];
|
||||||
if (self != nil) {
|
if (self != nil) {
|
||||||
_flowLayout = flowLayout;
|
_flowLayout = flowLayout;
|
||||||
@@ -32,17 +40,38 @@
|
|||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (ASCollectionView *)collectionView
|
||||||
|
{
|
||||||
|
return self.view;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDataSource:(id <ASPagerNodeDataSource>)pagerDataSource
|
||||||
|
{
|
||||||
|
if (pagerDataSource != _pagerDataSource) {
|
||||||
|
_pagerDataSource = pagerDataSource;
|
||||||
|
_proxy = pagerDataSource ? [[ASPagerNodeProxy alloc] initWithTarget:pagerDataSource interceptor:self] : nil;
|
||||||
|
super.dataSource = _proxy;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (id <ASPagerNodeDataSource>)dataSource
|
||||||
|
{
|
||||||
|
return _pagerDataSource;
|
||||||
|
}
|
||||||
|
|
||||||
- (void)didLoad
|
- (void)didLoad
|
||||||
{
|
{
|
||||||
[super didLoad];
|
[super didLoad];
|
||||||
|
|
||||||
self.view.asyncDataSource = self;
|
ASCollectionView *cv = self.view;
|
||||||
self.view.asyncDelegate = self;
|
cv.asyncDataSource = self;
|
||||||
|
cv.asyncDelegate = self;
|
||||||
|
|
||||||
self.view.pagingEnabled = YES;
|
cv.pagingEnabled = YES;
|
||||||
self.view.allowsSelection = NO;
|
cv.allowsSelection = NO;
|
||||||
self.view.showsVerticalScrollIndicator = NO;
|
cv.showsVerticalScrollIndicator = NO;
|
||||||
self.view.showsHorizontalScrollIndicator = NO;
|
cv.showsHorizontalScrollIndicator = NO;
|
||||||
|
cv.scrollsToTop = NO;
|
||||||
|
|
||||||
ASRangeTuningParameters preloadParams = { .leadingBufferScreenfuls = 2.0, .trailingBufferScreenfuls = 2.0 };
|
ASRangeTuningParameters preloadParams = { .leadingBufferScreenfuls = 2.0, .trailingBufferScreenfuls = 2.0 };
|
||||||
ASRangeTuningParameters renderParams = { .leadingBufferScreenfuls = 1.0, .trailingBufferScreenfuls = 1.0 };
|
ASRangeTuningParameters renderParams = { .leadingBufferScreenfuls = 1.0, .trailingBufferScreenfuls = 1.0 };
|
||||||
@@ -62,14 +91,14 @@
|
|||||||
|
|
||||||
- (ASCellNode *)collectionView:(ASCollectionView *)collectionView nodeForItemAtIndexPath:(NSIndexPath *)indexPath
|
- (ASCellNode *)collectionView:(ASCollectionView *)collectionView nodeForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(self.dataSource != nil, @"ASPagerNode must have a data source to load paging nodes");
|
ASDisplayNodeAssert(_pagerDataSource != nil, @"ASPagerNode must have a data source to load paging nodes");
|
||||||
return [self.dataSource pagerNode:self nodeAtIndex:indexPath.item];
|
return [_pagerDataSource pagerNode:self nodeAtIndex:indexPath.item];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
|
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(self.dataSource != nil, @"ASPagerNode must have a data source to load paging nodes");
|
ASDisplayNodeAssert(_pagerDataSource != nil, @"ASPagerNode must have a data source to load paging nodes");
|
||||||
return [self.dataSource numberOfPagesInPagerNode:self];
|
return [_pagerDataSource numberOfPagesInPagerNode:self];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
|
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
|
||||||
|
|||||||
@@ -18,4 +18,8 @@
|
|||||||
|
|
||||||
@property (nonatomic, readonly) ASTableView *view;
|
@property (nonatomic, readonly) ASTableView *view;
|
||||||
|
|
||||||
|
// These properties can be set without triggering the view to be created, so it's fine to set them in -init.
|
||||||
|
@property (weak, nonatomic) id <ASTableDelegate> delegate;
|
||||||
|
@property (weak, nonatomic) id <ASTableDataSource> dataSource;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|||||||
@@ -8,18 +8,71 @@
|
|||||||
|
|
||||||
#import "ASTableNode.h"
|
#import "ASTableNode.h"
|
||||||
|
|
||||||
|
@interface _ASTablePendingState : NSObject
|
||||||
|
@property (weak, nonatomic) id <ASTableDelegate> delegate;
|
||||||
|
@property (weak, nonatomic) id <ASTableDataSource> dataSource;
|
||||||
|
@end
|
||||||
|
|
||||||
|
@implementation _ASTablePendingState
|
||||||
|
@end
|
||||||
|
|
||||||
|
@interface ASTableNode ()
|
||||||
|
@property (nonatomic) _ASTablePendingState *pendingState;
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation ASTableNode
|
@implementation ASTableNode
|
||||||
|
|
||||||
- (instancetype)initWithStyle:(UITableViewStyle)style
|
- (instancetype)initWithStyle:(UITableViewStyle)style
|
||||||
{
|
{
|
||||||
if (self = [super initWithViewBlock:^UIView *{
|
if (self = [super initWithViewBlock:^UIView *{ return [[ASTableView alloc] initWithFrame:CGRectZero style:style]; }]) {
|
||||||
return [[ASTableView alloc] initWithFrame:CGRectZero style:style];
|
|
||||||
}]) {
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (void)didLoad
|
||||||
|
{
|
||||||
|
[super didLoad];
|
||||||
|
|
||||||
|
if (_pendingState) {
|
||||||
|
_ASTablePendingState *pendingState = _pendingState;
|
||||||
|
self.pendingState = nil;
|
||||||
|
|
||||||
|
ASTableView *view = self.view;
|
||||||
|
view.asyncDelegate = pendingState.delegate;
|
||||||
|
view.asyncDataSource = pendingState.dataSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (_ASTablePendingState *)pendingState
|
||||||
|
{
|
||||||
|
if (!_pendingState && ![self isNodeLoaded]) {
|
||||||
|
self.pendingState = [[_ASTablePendingState alloc] init];
|
||||||
|
}
|
||||||
|
ASDisplayNodeAssert(![self isNodeLoaded] || !_pendingState, @"ASTableNode should not have a pendingState once it is loaded");
|
||||||
|
return _pendingState;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDelegate:(id <ASTableDelegate>)delegate
|
||||||
|
{
|
||||||
|
if ([self pendingState]) {
|
||||||
|
_pendingState.delegate = delegate;
|
||||||
|
} else {
|
||||||
|
ASDisplayNodeAssert([self isNodeLoaded], @"ASTableNode should be loaded if pendingState doesn't exist");
|
||||||
|
self.view.asyncDelegate = delegate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setDataSource:(id <ASTableDataSource>)dataSource
|
||||||
|
{
|
||||||
|
if ([self pendingState]) {
|
||||||
|
_pendingState.dataSource = dataSource;
|
||||||
|
} else {
|
||||||
|
ASDisplayNodeAssert([self isNodeLoaded], @"ASTableNode should be loaded if pendingState doesn't exist");
|
||||||
|
self.view.asyncDataSource = dataSource;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
- (ASTableView *)view
|
- (ASTableView *)view
|
||||||
{
|
{
|
||||||
return (ASTableView *)[super view];
|
return (ASTableView *)[super view];
|
||||||
|
|||||||
@@ -280,6 +280,8 @@
|
|||||||
/**
|
/**
|
||||||
* This is a node-based UITableViewDataSource.
|
* This is a node-based UITableViewDataSource.
|
||||||
*/
|
*/
|
||||||
|
@protocol ASTableDataSource <ASTableViewDataSource>
|
||||||
|
@end
|
||||||
@protocol ASTableViewDataSource <ASCommonTableViewDataSource, NSObject>
|
@protocol ASTableViewDataSource <ASCommonTableViewDataSource, NSObject>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -324,6 +326,8 @@
|
|||||||
* Note that -tableView:heightForRowAtIndexPath: has been removed; instead, your custom ASCellNode subclasses are
|
* Note that -tableView:heightForRowAtIndexPath: has been removed; instead, your custom ASCellNode subclasses are
|
||||||
* responsible for deciding their preferred onscreen height in -calculateSizeThatFits:.
|
* responsible for deciding their preferred onscreen height in -calculateSizeThatFits:.
|
||||||
*/
|
*/
|
||||||
|
@protocol ASTableDelegate <ASTableViewDelegate>
|
||||||
|
@end
|
||||||
@protocol ASTableViewDelegate <ASCommonTableViewDelegate, NSObject>
|
@protocol ASTableViewDelegate <ASCommonTableViewDelegate, NSObject>
|
||||||
|
|
||||||
@optional
|
@optional
|
||||||
|
|||||||
@@ -49,3 +49,7 @@
|
|||||||
|
|
||||||
@interface ASCollectionViewProxy : ASDelegateProxy
|
@interface ASCollectionViewProxy : ASDelegateProxy
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@interface ASPagerNodeProxy : ASDelegateProxy
|
||||||
|
@end
|
||||||
|
|
||||||
|
|||||||
@@ -60,6 +60,20 @@
|
|||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@implementation ASPagerNodeProxy
|
||||||
|
|
||||||
|
- (BOOL)interceptsSelector:(SEL)selector
|
||||||
|
{
|
||||||
|
return (
|
||||||
|
// handled by ASPagerNodeDataSource node<->cell machinery
|
||||||
|
selector == @selector(collectionView:nodeForItemAtIndexPath:) ||
|
||||||
|
selector == @selector(collectionView:numberOfItemsInSection:) ||
|
||||||
|
selector == @selector(collectionView:constrainedSizeForNodeAtIndexPath:)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
@implementation ASDelegateProxy {
|
@implementation ASDelegateProxy {
|
||||||
id <NSObject> __weak _target;
|
id <NSObject> __weak _target;
|
||||||
id <ASDelegateProxyInterceptor> __weak _interceptor;
|
id <ASDelegateProxyInterceptor> __weak _interceptor;
|
||||||
|
|||||||
@@ -39,33 +39,34 @@
|
|||||||
|
|
||||||
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
|
- (ASLayout *)measureWithSizeRange:(ASSizeRange)constrainedSize
|
||||||
{
|
{
|
||||||
CGSize size = {
|
CGSize maxConstrainedSize = CGSizeMake(constrainedSize.max.width, constrainedSize.max.height);
|
||||||
constrainedSize.max.width,
|
|
||||||
constrainedSize.max.height
|
NSArray *children = self.children;
|
||||||
};
|
NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:children.count];
|
||||||
|
|
||||||
NSMutableArray *sublayouts = [NSMutableArray arrayWithCapacity:self.children.count];
|
for (id<ASLayoutable> child in children) {
|
||||||
for (id<ASLayoutable> child in self.children) {
|
CGPoint layoutPosition = child.layoutPosition;
|
||||||
CGSize autoMaxSize = {
|
CGSize autoMaxSize = CGSizeMake(maxConstrainedSize.width - layoutPosition.x,
|
||||||
constrainedSize.max.width - child.layoutPosition.x,
|
maxConstrainedSize.height - layoutPosition.y);
|
||||||
constrainedSize.max.height - child.layoutPosition.y
|
|
||||||
};
|
ASRelativeSizeRange childSizeRange = child.sizeRange;
|
||||||
ASSizeRange childConstraint = ASRelativeSizeRangeEqualToRelativeSizeRange(ASRelativeSizeRangeUnconstrained, child.sizeRange)
|
BOOL childIsUnconstrained = ASRelativeSizeRangeEqualToRelativeSizeRange(ASRelativeSizeRangeUnconstrained, childSizeRange);
|
||||||
? ASSizeRangeMake({0, 0}, autoMaxSize)
|
ASSizeRange childConstraint = childIsUnconstrained ? ASSizeRangeMake({0, 0}, autoMaxSize)
|
||||||
: ASRelativeSizeRangeResolve(child.sizeRange, size);
|
: ASRelativeSizeRangeResolve(childSizeRange, maxConstrainedSize);
|
||||||
|
|
||||||
ASLayout *sublayout = [child measureWithSizeRange:childConstraint];
|
ASLayout *sublayout = [child measureWithSizeRange:childConstraint];
|
||||||
sublayout.position = child.layoutPosition;
|
sublayout.position = layoutPosition;
|
||||||
[sublayouts addObject:sublayout];
|
[sublayouts addObject:sublayout];
|
||||||
}
|
}
|
||||||
|
|
||||||
size.width = constrainedSize.min.width;
|
CGSize size = CGSizeMake(constrainedSize.min.width, constrainedSize.min.height);
|
||||||
for (ASLayout *sublayout in sublayouts) {
|
|
||||||
size.width = MAX(size.width, sublayout.position.x + sublayout.size.width);
|
|
||||||
}
|
|
||||||
|
|
||||||
size.height = constrainedSize.min.height;
|
|
||||||
for (ASLayout *sublayout in sublayouts) {
|
for (ASLayout *sublayout in sublayouts) {
|
||||||
size.height = MAX(size.height, sublayout.position.y + sublayout.size.height);
|
CGPoint sublayoutPosition = sublayout.position;
|
||||||
|
CGSize sublayoutSize = sublayout.size;
|
||||||
|
|
||||||
|
size.width = MAX(size.width, sublayoutPosition.x + sublayoutSize.width);
|
||||||
|
size.height = MAX(size.height, sublayoutPosition.y + sublayoutSize.height);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [ASLayout layoutWithLayoutableObject:self
|
return [ASLayout layoutWithLayoutableObject:self
|
||||||
@@ -75,12 +76,12 @@
|
|||||||
|
|
||||||
- (void)setChild:(id<ASLayoutable>)child forIdentifier:(NSString *)identifier
|
- (void)setChild:(id<ASLayoutable>)child forIdentifier:(NSString *)identifier
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(NO, @"ASStackLayoutSpec only supports setChildren");
|
ASDisplayNodeAssert(NO, @"ASStaticLayoutSpec only supports setChildren");
|
||||||
}
|
}
|
||||||
|
|
||||||
- (id<ASLayoutable>)childForIdentifier:(NSString *)identifier
|
- (id<ASLayoutable>)childForIdentifier:(NSString *)identifier
|
||||||
{
|
{
|
||||||
ASDisplayNodeAssert(NO, @"ASStackLayoutSpec only supports children");
|
ASDisplayNodeAssert(NO, @"ASStaticLayoutSpec only supports children");
|
||||||
return nil;
|
return nil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user