mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-10 16:29:55 +00:00
[ASCollectionLayout] Add ASCollectionGalleryLayoutSizeProviding (#451)
* Add ASCollectionGalleryLayoutSizeProviding - This allows users to return different sizes based on certain conditions, such as the collection node's bounds or grid constants. - ASPagerNode will also act as a size provider to ensure all pages have an up-to-date size that is its bounds. * Update CHANGELOG * ASPagerNode to use gallery layout delegate if told to
This commit is contained in:
parent
7af8f91e62
commit
78c133e44c
@ -425,6 +425,7 @@
|
||||
DECBD6EA1BE56E1900CF4905 /* ASButtonNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = DECBD6E61BE56E1900CF4905 /* ASButtonNode.mm */; };
|
||||
DEFAD8131CC48914000527C4 /* ASVideoNode.mm in Sources */ = {isa = PBXBuildFile; fileRef = AEEC47E01C20C2DD00EC1693 /* ASVideoNode.mm */; };
|
||||
E51B78BF1F028ABF00E32604 /* ASLayoutFlatteningTests.m in Sources */ = {isa = PBXBuildFile; fileRef = E51B78BD1F01A0EE00E32604 /* ASLayoutFlatteningTests.m */; };
|
||||
E54E00721F1D3828000B30D7 /* ASPagerNode+Beta.h in Headers */ = {isa = PBXBuildFile; fileRef = E54E00711F1D3828000B30D7 /* ASPagerNode+Beta.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
E54E81FC1EB357BD00FFE8E1 /* ASPageTable.h in Headers */ = {isa = PBXBuildFile; fileRef = E54E81FA1EB357BD00FFE8E1 /* ASPageTable.h */; };
|
||||
E54E81FD1EB357BD00FFE8E1 /* ASPageTable.m in Sources */ = {isa = PBXBuildFile; fileRef = E54E81FB1EB357BD00FFE8E1 /* ASPageTable.m */; };
|
||||
E55D86331CA8A14000A0C26F /* ASLayoutElement.mm in Sources */ = {isa = PBXBuildFile; fileRef = E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */; };
|
||||
@ -912,6 +913,7 @@
|
||||
E51B78BD1F01A0EE00E32604 /* ASLayoutFlatteningTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASLayoutFlatteningTests.m; sourceTree = "<group>"; };
|
||||
E52405B21C8FEF03004DC8E7 /* ASLayoutTransition.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutTransition.mm; sourceTree = "<group>"; };
|
||||
E52405B41C8FEF16004DC8E7 /* ASLayoutTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASLayoutTransition.h; sourceTree = "<group>"; };
|
||||
E54E00711F1D3828000B30D7 /* ASPagerNode+Beta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "ASPagerNode+Beta.h"; sourceTree = "<group>"; };
|
||||
E54E81FA1EB357BD00FFE8E1 /* ASPageTable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ASPageTable.h; sourceTree = "<group>"; };
|
||||
E54E81FB1EB357BD00FFE8E1 /* ASPageTable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ASPageTable.m; sourceTree = "<group>"; };
|
||||
E55D86311CA8A14000A0C26F /* ASLayoutElement.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = ASLayoutElement.mm; sourceTree = "<group>"; };
|
||||
@ -1101,6 +1103,7 @@
|
||||
698371DA1E4379CD00437585 /* ASNodeController+Beta.m */,
|
||||
25E327541C16819500A2170C /* ASPagerNode.h */,
|
||||
25E327551C16819500A2170C /* ASPagerNode.m */,
|
||||
E54E00711F1D3828000B30D7 /* ASPagerNode+Beta.h */,
|
||||
A2763D771CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.h */,
|
||||
A2763D781CBDD57D00A9ADBD /* ASPINRemoteImageDownloader.m */,
|
||||
CCBBBF5C1EB161760069AA91 /* ASRangeManagingNode.h */,
|
||||
@ -1708,6 +1711,7 @@
|
||||
isa = PBXHeadersBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
E54E00721F1D3828000B30D7 /* ASPagerNode+Beta.h in Headers */,
|
||||
E5B225281F1790D6001E1431 /* ASHashing.h in Headers */,
|
||||
CC034A131E649F1300626263 /* AsyncDisplayKit+IGListKitMethods.h in Headers */,
|
||||
693A1DCA1ECC944E00D0C9D2 /* IGListAdapter+AsyncDisplayKit.h in Headers */,
|
||||
|
||||
@ -4,7 +4,7 @@
|
||||
- [ASCollectionView] Add delegate bridging and index space translation for missing UICollectionViewLayout properties. [Scott Goodson](https://github.com/appleguy)
|
||||
- [ASTextNode2] Add initial implementation for link handling. [Scott Goodson](https://github.com/appleguy) [#396](https://github.com/TextureGroup/Texture/pull/396)
|
||||
- [ASTextNode2] Provide compile flag to globally enable new implementation of ASTextNode: ASTEXTNODE_EXPERIMENT_GLOBAL_ENABLE. [Scott Goodson](https://github.com/appleguy) [#396](https://github.com/TextureGroup/Texture/pull/410)
|
||||
- Add ASCollectionGalleryLayoutDelegate - an async collection layout that makes same-size collections (e.g photo galleries, pagers, etc) fast and lightweight! [Huy Nguyen](https://github.com/nguyenhuy/) [#76](https://github.com/TextureGroup/Texture/pull/76)
|
||||
- Add ASCollectionGalleryLayoutDelegate - an async collection layout that makes same-size collections (e.g photo galleries, pagers, etc) fast and lightweight! [Huy Nguyen](https://github.com/nguyenhuy/) [#76](https://github.com/TextureGroup/Texture/pull/76) [#451](https://github.com/TextureGroup/Texture/pull/451)
|
||||
|
||||
##2.3.5
|
||||
- Fix an issue where inserting/deleting sections could lead to inconsistent supplementary element behavior. [Adlai Holler](https://github.com/Adlai-Holler)
|
||||
|
||||
19
Source/ASPagerNode+Beta.h
Normal file
19
Source/ASPagerNode+Beta.h
Normal file
@ -0,0 +1,19 @@
|
||||
//
|
||||
// ASPagerNode+Beta.h
|
||||
// Texture
|
||||
//
|
||||
// Copyright (c) 2017-present, Pinterest, Inc. All rights reserved.
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
|
||||
#import <AsyncDisplayKit/ASPagerNode.h>
|
||||
|
||||
@interface ASPagerNode (Beta)
|
||||
|
||||
- (instancetype)initUsingAsyncCollectionLayout;
|
||||
|
||||
@end
|
||||
@ -16,6 +16,10 @@
|
||||
//
|
||||
|
||||
#import <AsyncDisplayKit/ASPagerNode.h>
|
||||
#import <AsyncDisplayKit/ASPagerNode+Beta.h>
|
||||
|
||||
#import <AsyncDisplayKit/ASCollectionGalleryLayoutDelegate.h>
|
||||
#import <AsyncDisplayKit/ASCollectionNode+Beta.h>
|
||||
#import <AsyncDisplayKit/ASDelegateProxy.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+FrameworkPrivate.h>
|
||||
#import <AsyncDisplayKit/ASDisplayNode+Subclasses.h>
|
||||
@ -25,7 +29,7 @@
|
||||
#import <AsyncDisplayKit/ASCollectionView+Undeprecated.h>
|
||||
#import <AsyncDisplayKit/UIResponder+AsyncDisplayKit.h>
|
||||
|
||||
@interface ASPagerNode () <ASCollectionDataSource, ASCollectionDelegate, ASCollectionDelegateFlowLayout, ASDelegateProxyInterceptor>
|
||||
@interface ASPagerNode () <ASCollectionDataSource, ASCollectionDelegate, ASCollectionDelegateFlowLayout, ASDelegateProxyInterceptor, ASCollectionGalleryLayoutSizeProviding>
|
||||
{
|
||||
__weak id <ASPagerDataSource> _pagerDataSource;
|
||||
ASPagerNodeProxy *_proxyDataSource;
|
||||
@ -66,6 +70,16 @@
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initUsingAsyncCollectionLayout
|
||||
{
|
||||
ASCollectionGalleryLayoutDelegate *layoutDelegate = [[ASCollectionGalleryLayoutDelegate alloc] initWithScrollableDirections:ASScrollDirectionHorizontalDirections];
|
||||
self = [super initWithLayoutDelegate:layoutDelegate layoutFacilitator:nil];
|
||||
if (self) {
|
||||
layoutDelegate.sizeProvider = self;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
#pragma mark - ASDisplayNode
|
||||
|
||||
- (void)didLoad
|
||||
@ -123,6 +137,14 @@
|
||||
return indexPath.row;
|
||||
}
|
||||
|
||||
#pragma mark - ASCollectionGalleryLayoutSizeProviding
|
||||
|
||||
- (CGSize)sizeForElements:(ASElementMap *)elements
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
return self.bounds.size;
|
||||
}
|
||||
|
||||
#pragma mark - ASCollectionDataSource
|
||||
|
||||
- (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
|
||||
@ -46,11 +46,13 @@
|
||||
|
||||
- (ASScrollDirection)scrollableDirections
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
return _scrollableDirections;
|
||||
}
|
||||
|
||||
- (id)additionalInfoForLayoutWithElements:(ASElementMap *)elements
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
return nil;
|
||||
}
|
||||
|
||||
@ -59,9 +61,7 @@
|
||||
ASElementMap *elements = context.elements;
|
||||
NSMutableArray<ASCellNode *> *children = ASArrayByFlatMapping(elements.itemElements, ASCollectionElement *element, element.node);
|
||||
if (children.count == 0) {
|
||||
return [[ASCollectionLayoutState alloc] initWithContext:context
|
||||
contentSize:CGSizeZero
|
||||
elementToLayoutAttributesTable:[NSMapTable elementToLayoutAttributesTable]];
|
||||
return [[ASCollectionLayoutState alloc] initWithContext:context];
|
||||
}
|
||||
|
||||
ASStackLayoutSpec *stackSpec = [ASStackLayoutSpec stackLayoutSpecWithDirection:ASStackLayoutDirectionHorizontal
|
||||
|
||||
@ -13,8 +13,25 @@
|
||||
#import <AsyncDisplayKit/ASCollectionLayoutDelegate.h>
|
||||
#import <AsyncDisplayKit/ASScrollDirection.h>
|
||||
|
||||
@class ASElementMap;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@protocol ASCollectionGalleryLayoutSizeProviding <NSObject>
|
||||
|
||||
/**
|
||||
* Returns the fixed size of each and every element.
|
||||
*
|
||||
* @discussion This method will only be called on main thread.
|
||||
*
|
||||
* @param elements All elements to be sized.
|
||||
*
|
||||
* @return The elements' size
|
||||
*/
|
||||
- (CGSize)sizeForElements:(ASElementMap *)elements;
|
||||
|
||||
@end
|
||||
|
||||
/**
|
||||
* A thread-safe layout delegate that arranges items with the same size into a flow layout.
|
||||
*
|
||||
@ -23,7 +40,9 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
AS_SUBCLASSING_RESTRICTED
|
||||
@interface ASCollectionGalleryLayoutDelegate : NSObject <ASCollectionLayoutDelegate>
|
||||
|
||||
- (instancetype)initWithScrollableDirections:(ASScrollDirection)scrollableDirections itemSize:(CGSize)itemSize NS_DESIGNATED_INITIALIZER;
|
||||
@property (nonatomic, weak) id<ASCollectionGalleryLayoutSizeProviding> sizeProvider;
|
||||
|
||||
- (instancetype)initWithScrollableDirections:(ASScrollDirection)scrollableDirections NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
- (instancetype)init __unavailable;
|
||||
|
||||
|
||||
@ -31,40 +31,47 @@
|
||||
CGSize _itemSize;
|
||||
}
|
||||
|
||||
- (instancetype)initWithScrollableDirections:(ASScrollDirection)scrollableDirections itemSize:(CGSize)itemSize
|
||||
- (instancetype)initWithScrollableDirections:(ASScrollDirection)scrollableDirections
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
ASDisplayNodeAssertFalse(CGSizeEqualToSize(CGSizeZero, itemSize));
|
||||
_scrollableDirections = scrollableDirections;
|
||||
_itemSize = itemSize;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (ASScrollDirection)scrollableDirections
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
return _scrollableDirections;
|
||||
}
|
||||
|
||||
- (id)additionalInfoForLayoutWithElements:(ASElementMap *)elements
|
||||
{
|
||||
return [NSValue valueWithCGSize:_itemSize];
|
||||
ASDisplayNodeAssertMainThread();
|
||||
if (_sizeProvider == nil) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
return [NSValue valueWithCGSize:[_sizeProvider sizeForElements:elements]];
|
||||
}
|
||||
|
||||
+ (ASCollectionLayoutState *)calculateLayoutWithContext:(ASCollectionLayoutContext *)context
|
||||
{
|
||||
ASElementMap *elements = context.elements;
|
||||
CGSize pageSize = context.viewportSize;
|
||||
CGSize itemSize = ((NSValue *)context.additionalInfo).CGSizeValue;
|
||||
ASScrollDirection scrollableDirections = context.scrollableDirections;
|
||||
|
||||
CGSize itemSize = context.additionalInfo ? ((NSValue *)context.additionalInfo).CGSizeValue : CGSizeZero;
|
||||
if (CGSizeEqualToSize(CGSizeZero, itemSize)) {
|
||||
return [[ASCollectionLayoutState alloc] initWithContext:context];
|
||||
}
|
||||
|
||||
NSMutableArray<_ASGalleryLayoutItem *> *children = ASArrayByFlatMapping(elements.itemElements,
|
||||
ASCollectionElement *element,
|
||||
[[_ASGalleryLayoutItem alloc] initWithItemSize:itemSize collectionElement:element]);
|
||||
ASCollectionElement *element,
|
||||
[[_ASGalleryLayoutItem alloc] initWithItemSize:itemSize collectionElement:element]);
|
||||
if (children.count == 0) {
|
||||
return [[ASCollectionLayoutState alloc] initWithContext:context
|
||||
contentSize:CGSizeZero
|
||||
elementToLayoutAttributesTable:[NSMapTable weakToStrongObjectsMapTable]];
|
||||
return [[ASCollectionLayoutState alloc] initWithContext:context];
|
||||
}
|
||||
|
||||
// Use a stack spec to calculate layout content size and frames of all elements without actually measuring each element
|
||||
|
||||
@ -37,7 +37,6 @@
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
ASDisplayNodeAssertTrue([layoutDelegateClass conformsToProtocol:@protocol(ASCollectionLayoutDelegate)]);
|
||||
_viewportSize = viewportSize;
|
||||
_scrollableDirections = scrollableDirections;
|
||||
_elements = elements;
|
||||
|
||||
@ -30,6 +30,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
* It will be available in the context parameter in +calculateLayoutWithContext:
|
||||
*
|
||||
* @return The scrollable directions.
|
||||
*
|
||||
* @discusstion This method will be called on main thread.
|
||||
*/
|
||||
- (ASScrollDirection)scrollableDirections;
|
||||
|
||||
|
||||
@ -56,6 +56,13 @@ AS_SUBCLASSING_RESTRICTED
|
||||
contentSize:(CGSize)contentSize
|
||||
elementToLayoutAttributesTable:(NSMapTable<ASCollectionElement *, UICollectionViewLayoutAttributes *> *)table NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
/**
|
||||
* Convenience initializer. Returns an object with zero content size and an empty table.
|
||||
*
|
||||
* @param context The context used to calculate this object
|
||||
*/
|
||||
- (instancetype)initWithContext:(ASCollectionLayoutContext *)context;
|
||||
|
||||
/**
|
||||
* Convenience initializer.
|
||||
*
|
||||
|
||||
@ -39,6 +39,13 @@
|
||||
ASPageToLayoutAttributesTable *_unmeasuredPageToLayoutAttributesTable;
|
||||
}
|
||||
|
||||
- (instancetype)initWithContext:(ASCollectionLayoutContext *)context
|
||||
{
|
||||
return [self initWithContext:context
|
||||
contentSize:CGSizeZero
|
||||
elementToLayoutAttributesTable:[NSMapTable elementToLayoutAttributesTable]];
|
||||
}
|
||||
|
||||
- (instancetype)initWithContext:(ASCollectionLayoutContext *)context
|
||||
layout:(ASLayout *)layout
|
||||
getElementBlock:(ASCollectionElement *(^)(ASLayout *))getElementBlock
|
||||
|
||||
@ -85,12 +85,9 @@ static const ASScrollDirection kASStaticScrollDirection = (ASScrollDirectionRigh
|
||||
+ (ASCollectionLayoutState *)calculateLayoutWithContext:(ASCollectionLayoutContext *)context
|
||||
{
|
||||
if (context.elements == nil) {
|
||||
return [[ASCollectionLayoutState alloc] initWithContext:context
|
||||
contentSize:CGSizeZero
|
||||
elementToLayoutAttributesTable:[NSMapTable elementToLayoutAttributesTable]];
|
||||
return [[ASCollectionLayoutState alloc] initWithContext:context];
|
||||
}
|
||||
|
||||
ASDisplayNodeAssertTrue([context.layoutDelegateClass conformsToProtocol:@protocol(ASCollectionLayoutDelegate)]);
|
||||
ASCollectionLayoutState *layout = [context.layoutDelegateClass calculateLayoutWithContext:context];
|
||||
[context.layoutCache setLayout:layout forContext:context];
|
||||
|
||||
|
||||
@ -23,7 +23,7 @@
|
||||
|
||||
#define ASYNC_COLLECTION_LAYOUT 0
|
||||
|
||||
@interface ViewController () <ASCollectionDataSource, ASCollectionDelegateFlowLayout>
|
||||
@interface ViewController () <ASCollectionDataSource, ASCollectionDelegateFlowLayout, ASCollectionGalleryLayoutSizeProviding>
|
||||
|
||||
@property (nonatomic, strong) ASCollectionNode *collectionNode;
|
||||
@property (nonatomic, strong) NSArray *data;
|
||||
@ -47,8 +47,8 @@
|
||||
[super viewDidLoad];
|
||||
|
||||
#if ASYNC_COLLECTION_LAYOUT
|
||||
id<ASCollectionLayoutDelegate> layoutDelegate = [[ASCollectionGalleryLayoutDelegate alloc] initWithScrollableDirections:ASScrollDirectionVerticalDirections
|
||||
itemSize:CGSizeMake(180, 90)];
|
||||
ASCollectionGalleryLayoutDelegate *layoutDelegate = [[ASCollectionGalleryLayoutDelegate alloc] initWithScrollableDirections:ASScrollDirectionVerticalDirections];
|
||||
layoutDelegate.sizeProvider = self;
|
||||
self.collectionNode = [[ASCollectionNode alloc] initWithLayoutDelegate:layoutDelegate layoutFacilitator:nil];
|
||||
#else
|
||||
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
|
||||
@ -108,6 +108,14 @@
|
||||
[self.collectionNode reloadData];
|
||||
}
|
||||
|
||||
#pragma mark - ASCollectionGalleryLayoutSizeProviding
|
||||
|
||||
- (CGSize)sizeForElements:(ASElementMap *)elements
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
return CGSizeMake(180, 90);
|
||||
}
|
||||
|
||||
#pragma mark - ASCollectionView Data Source
|
||||
|
||||
- (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath;
|
||||
|
||||
@ -36,11 +36,13 @@
|
||||
|
||||
- (ASScrollDirection)scrollableDirections
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
return ASScrollDirectionVerticalDirections;
|
||||
}
|
||||
|
||||
- (id)additionalInfoForLayoutWithElements:(ASElementMap *)elements
|
||||
{
|
||||
ASDisplayNodeAssertMainThread();
|
||||
return _info;
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user