mirror of
https://github.com/Swiftgram/Telegram-iOS.git
synced 2025-12-10 08:20:16 +00:00
[Examples] 2.0 Collection/Table API updates (#2390)
* update VerticalWithinHorizontal example * update SocialAppLayout * update Kittens * update HorizontalWithinVerticalScrolling * update AsyncDisplayKitOverview * update CustomCollectionView * CatDealsCollectionView * update Swift * address @appleguy's comment * updates for tableNode deselectRowAtIndexPath
This commit is contained in:
parent
0d439a43b6
commit
0b7dfcc54d
@ -66,7 +66,7 @@
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
[self.tableNode.view deselectRowAtIndexPath:self.tableNode.view.indexPathForSelectedRow animated:YES];
|
||||
[self.tableNode deselectRowAtIndexPath:self.tableNode.view.indexPathForSelectedRow animated:YES];
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -53,12 +53,12 @@
|
||||
|
||||
#pragma mark - <ASCollectionDataSource, ASCollectionDelegate>
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
|
||||
- (NSInteger)collectionNode:(ASCollectionNode *)collectionNode numberOfItemsInSection:(NSInteger)section
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
- (ASCellNodeBlock)collectionView:(ASCollectionView *)collectionView nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return ^{
|
||||
ASTextCellNode *cellNode = [ASTextCellNode new];
|
||||
@ -68,7 +68,7 @@
|
||||
};
|
||||
}
|
||||
|
||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (ASSizeRange)collectionNode:(ASCollectionNode *)collectionNode constrainedSizeForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return ASSizeRangeMake(CGSizeMake(100, 100));
|
||||
}
|
||||
|
||||
@ -51,12 +51,12 @@
|
||||
|
||||
#pragma mark - <ASCollectionDataSource, ASCollectionDelegate>
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
- (NSInteger)tableNode:(ASTableNode *)tableNode numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
- (ASCellNodeBlock)tableView:(ASTableView *)tableView nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (ASCellNodeBlock)tableNode:(ASTableNode *)tableNode nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return ^{
|
||||
ASTextCellNode *cellNode = [ASTextCellNode new];
|
||||
|
||||
@ -17,7 +17,7 @@
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
|
||||
|
||||
@protocol ASLayoutSpecListEntry <NSObject>
|
||||
@ -27,7 +27,7 @@
|
||||
|
||||
@end
|
||||
|
||||
@interface OverviewComponentsViewController : UIViewController
|
||||
@interface OverviewComponentsViewController : ASViewController
|
||||
|
||||
|
||||
@end
|
||||
|
||||
@ -31,12 +31,15 @@
|
||||
|
||||
typedef ASLayoutSpec *(^OverviewDisplayNodeSizeThatFitsBlock)(ASSizeRange constrainedSize);
|
||||
|
||||
|
||||
#pragma mark - OverviewDisplayNodeWithSizeBlock
|
||||
|
||||
@interface OverviewDisplayNodeWithSizeBlock : ASDisplayNode<ASLayoutSpecListEntry>
|
||||
|
||||
@property (nonatomic, copy) NSString *entryTitle;
|
||||
@property (nonatomic, copy) NSString *entryDescription;
|
||||
@property (nonatomic, copy) OverviewDisplayNodeSizeThatFitsBlock sizeThatFitsBlock;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OverviewDisplayNodeWithSizeBlock
|
||||
@ -54,11 +57,14 @@ typedef ASLayoutSpec *(^OverviewDisplayNodeSizeThatFitsBlock)(ASSizeRange constr
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - OverviewTitleDescriptionCellNode
|
||||
|
||||
@interface OverviewTitleDescriptionCellNode : ASCellNode
|
||||
|
||||
@property (nonatomic, strong) ASTextNode *titleNode;
|
||||
@property (nonatomic, strong) ASTextNode *descriptionNode;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OverviewTitleDescriptionCellNode
|
||||
@ -91,16 +97,35 @@ typedef ASLayoutSpec *(^OverviewDisplayNodeSizeThatFitsBlock)(ASSizeRange constr
|
||||
|
||||
@end
|
||||
|
||||
|
||||
#pragma mark - OverviewComponentsViewController
|
||||
|
||||
@interface OverviewComponentsViewController ()
|
||||
|
||||
@property (nonatomic, copy) NSArray *data;
|
||||
@property (nonatomic, strong) ASTableNode *tableNode;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OverviewComponentsViewController
|
||||
|
||||
#pragma mark - UIViewController
|
||||
|
||||
#pragma mark - Lifecycle Methods
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
_tableNode = [ASTableNode new];
|
||||
|
||||
self = [super initWithNode:_tableNode];
|
||||
|
||||
if (self) {
|
||||
_tableNode.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
_tableNode.delegate = (id<ASTableDelegate>)self;
|
||||
_tableNode.dataSource = (id<ASTableDataSource>)self;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
@ -109,18 +134,17 @@ typedef ASLayoutSpec *(^OverviewDisplayNodeSizeThatFitsBlock)(ASSizeRange constr
|
||||
self.title = @"AsyncDisplayKit";
|
||||
|
||||
[self setupData];
|
||||
[self setupTableNode];
|
||||
}
|
||||
|
||||
- (void)viewWillAppear:(BOOL)animated
|
||||
{
|
||||
[super viewWillAppear:animated];
|
||||
|
||||
ASTableView *tableView = self.tableNode.view;
|
||||
[tableView deselectRowAtIndexPath:tableView.indexPathForSelectedRow animated:YES];
|
||||
[_tableNode deselectRowAtIndexPath:_tableNode.view.indexPathForSelectedRow animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark - Setup
|
||||
|
||||
#pragma mark - Data Model
|
||||
|
||||
- (void)setupData
|
||||
{
|
||||
@ -452,16 +476,6 @@ typedef ASLayoutSpec *(^OverviewDisplayNodeSizeThatFitsBlock)(ASSizeRange constr
|
||||
self.data = mutableData;
|
||||
}
|
||||
|
||||
- (void)setupTableNode
|
||||
{
|
||||
_tableNode = [ASTableNode new];
|
||||
_tableNode.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
_tableNode.frame = self.view.bounds;
|
||||
_tableNode.delegate = (id<ASTableDelegate>)self;
|
||||
_tableNode.dataSource = (id<ASTableDataSource>)self;
|
||||
[self.view addSubnode:_tableNode];
|
||||
}
|
||||
|
||||
#pragma mark - Parent / Child Helper
|
||||
|
||||
- (OverviewDisplayNodeWithSizeBlock *)parentNodeWithChild:(ASDisplayNode *)child
|
||||
@ -505,22 +519,22 @@ typedef ASLayoutSpec *(^OverviewDisplayNodeSizeThatFitsBlock)(ASSizeRange constr
|
||||
|
||||
#pragma mark - <ASTableDataSource / ASTableDelegate>
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
|
||||
- (NSInteger)numberOfSectionsInTableNode:(ASTableNode *)tableNode
|
||||
{
|
||||
return self.data.count;
|
||||
}
|
||||
|
||||
- (nullable NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
|
||||
- (nullable NSString *)tableNode:(ASTableNode *)tableNode titleForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
return self.data[section][@"title"];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(ASTableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
- (NSInteger)tableNode:(ASTableNode *)tableNode numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return [self.data[section][@"data"] count];
|
||||
}
|
||||
|
||||
- (ASCellNodeBlock)tableView:(ASTableView *)tableView nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (ASCellNodeBlock)tableNode:(ASTableNode *)tableNode nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
// You should get the node or data you want to pass to the cell node outside of the ASCellNodeBlock
|
||||
ASDisplayNode<ASLayoutSpecListEntry> *node = self.data[indexPath.section][@"data"][indexPath.row];
|
||||
@ -542,7 +556,7 @@ typedef ASLayoutSpec *(^OverviewDisplayNodeSizeThatFitsBlock)(ASSizeRange constr
|
||||
};
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (void)tableNode:(ASTableNode *)tableNode didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
ASDisplayNode *node = self.data[indexPath.section][@"data"][indexPath.row];
|
||||
OverviewDetailViewController *detail = [[OverviewDetailViewController alloc] initWithNode:node];
|
||||
|
||||
@ -29,7 +29,7 @@ static const NSInteger kBatchSize = 20;
|
||||
static const CGFloat kHorizontalSectionPadding = 10.0f;
|
||||
static const CGFloat kVerticalSectionPadding = 20.0f;
|
||||
|
||||
@interface ViewController () <ASCollectionDataSource, ASCollectionViewDelegateFlowLayout>
|
||||
@interface ViewController () <ASCollectionDataSource, ASCollectionDelegate, ASCollectionViewDelegateFlowLayout>
|
||||
{
|
||||
ASCollectionNode *_collectionNode;
|
||||
NSMutableArray *_data;
|
||||
@ -45,15 +45,15 @@ static const CGFloat kVerticalSectionPadding = 20.0f;
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
|
||||
_collectionNode = [[ASCollectionNode alloc] initWithCollectionViewLayout:layout];
|
||||
|
||||
self = [super initWithNode:_collectionNode];
|
||||
|
||||
if (self) {
|
||||
|
||||
self.title = @"Cat Deals";
|
||||
|
||||
UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
|
||||
|
||||
_collectionNode = [[ASCollectionNode alloc] initWithCollectionViewLayout:layout];
|
||||
|
||||
_collectionNode.dataSource = self;
|
||||
_collectionNode.delegate = self;
|
||||
_collectionNode.backgroundColor = [UIColor grayColor];
|
||||
@ -63,10 +63,10 @@ static const CGFloat kVerticalSectionPadding = 20.0f;
|
||||
preloadTuning.trailingBufferScreenfuls = 1;
|
||||
[_collectionNode setTuningParameters:preloadTuning forRangeType:ASLayoutRangeTypePreload];
|
||||
|
||||
ASRangeTuningParameters preRenderTuning;
|
||||
preRenderTuning.leadingBufferScreenfuls = 1;
|
||||
preRenderTuning.trailingBufferScreenfuls = 0.5;
|
||||
[_collectionNode setTuningParameters:preRenderTuning forRangeType:ASLayoutRangeTypeDisplay];
|
||||
ASRangeTuningParameters displayTuning;
|
||||
displayTuning.leadingBufferScreenfuls = 1;
|
||||
displayTuning.trailingBufferScreenfuls = 0.5;
|
||||
[_collectionNode setTuningParameters:displayTuning forRangeType:ASLayoutRangeTypeDisplay];
|
||||
|
||||
[_collectionNode registerSupplementaryNodeOfKind:UICollectionElementKindSectionHeader];
|
||||
[_collectionNode registerSupplementaryNodeOfKind:UICollectionElementKindSectionFooter];
|
||||
@ -151,10 +151,9 @@ static const CGFloat kVerticalSectionPadding = 20.0f;
|
||||
[_collectionNode reloadData];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark ASCollectionView data source.
|
||||
#pragma mark - ASCollectionNodeDelegate / ASCollectionNodeDataSource
|
||||
|
||||
- (ASCellNodeBlock)collectionView:(ASCollectionView *)collectionView nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
ItemViewModel *viewModel = _data[indexPath.item];
|
||||
return ^{
|
||||
@ -162,7 +161,8 @@ static const CGFloat kVerticalSectionPadding = 20.0f;
|
||||
};
|
||||
}
|
||||
|
||||
- (ASCellNode *)collectionView:(UICollectionView *)collectionView nodeForSupplementaryElementOfKind:(nonnull NSString *)kind atIndexPath:(nonnull NSIndexPath *)indexPath {
|
||||
- (ASCellNode *)collectionNode:(ASCollectionNode *)collectionNode nodeForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if ([kind isEqualToString:UICollectionElementKindSectionHeader] && indexPath.section == 0) {
|
||||
return [[BlurbNode alloc] init];
|
||||
} else if ([kind isEqualToString:UICollectionElementKindSectionFooter] && indexPath.section == 0) {
|
||||
@ -171,6 +171,44 @@ static const CGFloat kVerticalSectionPadding = 20.0f;
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (ASSizeRange)collectionNode:(ASCollectionNode *)collectionNode constrainedSizeForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
CGFloat collectionViewWidth = CGRectGetWidth(self.view.frame) - 2 * kHorizontalSectionPadding;
|
||||
CGFloat oneItemWidth = [ItemNode preferredViewSize].width;
|
||||
NSInteger numColumns = floor(collectionViewWidth / oneItemWidth);
|
||||
// Number of columns should be at least 1
|
||||
numColumns = MAX(1, numColumns);
|
||||
|
||||
CGFloat totalSpaceBetweenColumns = (numColumns - 1) * kHorizontalSectionPadding;
|
||||
CGFloat itemWidth = ((collectionViewWidth - totalSpaceBetweenColumns) / numColumns);
|
||||
CGSize itemSize = [ItemNode sizeForWidth:itemWidth];
|
||||
return ASSizeRangeMake(itemSize, itemSize);
|
||||
}
|
||||
|
||||
- (NSInteger)collectionNode:(ASCollectionNode *)collectionNode numberOfItemsInSection:(NSInteger)section
|
||||
{
|
||||
return [_data count];
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInCollectionNode:(ASCollectionNode *)collectionNode
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (void)collectionNode:(ASCollectionNode *)collectionNode willBeginBatchFetchWithContext:(ASBatchContext *)context
|
||||
{
|
||||
NSLog(@"fetch additional content");
|
||||
[self fetchMoreCatsWithCompletion:^(BOOL finished){
|
||||
[context completeBatchFetching:YES];
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark - ASCollectionViewDelegateFlowLayout
|
||||
|
||||
- (UIEdgeInsets)collectionView:(ASCollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
|
||||
return UIEdgeInsetsMake(kVerticalSectionPadding, kHorizontalSectionPadding, kVerticalSectionPadding, kHorizontalSectionPadding);
|
||||
}
|
||||
|
||||
- (CGSize)collectionView:(ASCollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
|
||||
if (section == 0) {
|
||||
CGFloat width = CGRectGetWidth(self.view.frame) - 2 * kHorizontalSectionPadding;
|
||||
@ -187,55 +225,5 @@ static const CGFloat kVerticalSectionPadding = 20.0f;
|
||||
return CGSizeZero;
|
||||
}
|
||||
|
||||
- (ASSizeRange)collectionView:(ASCollectionView *)collectionView constrainedSizeForNodeAtIndexPath:(NSIndexPath *)indexPath {
|
||||
CGFloat collectionViewWidth = CGRectGetWidth(self.view.frame) - 2 * kHorizontalSectionPadding;
|
||||
CGFloat oneItemWidth = [ItemNode preferredViewSize].width;
|
||||
NSInteger numColumns = floor(collectionViewWidth / oneItemWidth);
|
||||
// Number of columns should be at least 1
|
||||
numColumns = MAX(1, numColumns);
|
||||
|
||||
CGFloat totalSpaceBetweenColumns = (numColumns - 1) * kHorizontalSectionPadding;
|
||||
CGFloat itemWidth = ((collectionViewWidth - totalSpaceBetweenColumns) / numColumns);
|
||||
CGSize itemSize = [ItemNode sizeForWidth:itemWidth];
|
||||
return ASSizeRangeMake(itemSize, itemSize);
|
||||
}
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
|
||||
{
|
||||
return [_data count];
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (void)collectionViewLockDataSource:(ASCollectionView *)collectionView
|
||||
{
|
||||
// lock the data source
|
||||
// The data source should not be change until it is unlocked.
|
||||
}
|
||||
|
||||
- (void)collectionViewUnlockDataSource:(ASCollectionView *)collectionView
|
||||
{
|
||||
// unlock the data source to enable data source updating.
|
||||
}
|
||||
|
||||
- (void)collectionView:(UICollectionView *)collectionView willBeginBatchFetchWithContext:(ASBatchContext *)context
|
||||
{
|
||||
NSLog(@"fetch additional content");
|
||||
[self fetchMoreCatsWithCompletion:^(BOOL finished){
|
||||
[context completeBatchFetching:YES];
|
||||
}];
|
||||
}
|
||||
|
||||
- (UIEdgeInsets)collectionView:(ASCollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
|
||||
return UIEdgeInsetsMake(kVerticalSectionPadding, kHorizontalSectionPadding, kVerticalSectionPadding, kHorizontalSectionPadding);
|
||||
}
|
||||
|
||||
-(void)dealloc
|
||||
{
|
||||
NSLog(@"ViewController is deallocing");
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
self.window.backgroundColor = [UIColor whiteColor];
|
||||
self.window.rootViewController = [[ViewController alloc] init];
|
||||
|
||||
|
||||
[self.window makeKeyAndVisible];
|
||||
|
||||
return YES;
|
||||
|
||||
@ -39,6 +39,17 @@ static NSUInteger kNumberOfImages = 14;
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
MosaicCollectionViewLayout *layout = [[MosaicCollectionViewLayout alloc] init];
|
||||
layout.numberOfColumns = 2;
|
||||
layout.headerHeight = 44.0;
|
||||
|
||||
_collectionNode = [[ASCollectionNode alloc] initWithCollectionViewLayout:layout];
|
||||
_collectionNode.dataSource = self;
|
||||
_collectionNode.delegate = self;
|
||||
_collectionNode.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
_layoutInspector = [[MosaicCollectionViewLayoutInspector alloc] init];
|
||||
|
||||
if (!(self = [super initWithNode:_collectionNode]))
|
||||
return nil;
|
||||
|
||||
@ -53,16 +64,6 @@ static NSUInteger kNumberOfImages = 14;
|
||||
}
|
||||
}
|
||||
|
||||
MosaicCollectionViewLayout *layout = [[MosaicCollectionViewLayout alloc] init];
|
||||
layout.numberOfColumns = 2;
|
||||
layout.headerHeight = 44.0;
|
||||
|
||||
_layoutInspector = [[MosaicCollectionViewLayoutInspector alloc] init];
|
||||
|
||||
_collectionNode.dataSource = self;
|
||||
_collectionNode.delegate = self;
|
||||
_collectionNode.backgroundColor = [UIColor whiteColor];
|
||||
|
||||
[_collectionNode registerSupplementaryNodeOfKind:UICollectionElementKindSectionHeader];
|
||||
|
||||
return self;
|
||||
@ -75,19 +76,12 @@ static NSUInteger kNumberOfImages = 14;
|
||||
_collectionNode.view.layoutInspector = _layoutInspector;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
_collectionNode.dataSource = nil;
|
||||
_collectionNode.delegate = nil;
|
||||
}
|
||||
|
||||
- (void)reloadTapped
|
||||
{
|
||||
[_collectionNode reloadData];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark ASCollectionView data source.
|
||||
#pragma mark - ASCollectionNode data source.
|
||||
|
||||
- (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
@ -110,12 +104,12 @@ static NSUInteger kNumberOfImages = 14;
|
||||
return textCellNode;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInCollectionView:(ASCollectionNode *)collectionNode
|
||||
- (NSInteger)numberOfSectionsInCollectionNode:(ASCollectionNode *)collectionNode
|
||||
{
|
||||
return _sections.count;
|
||||
}
|
||||
|
||||
- (NSInteger)collectionView:(ASCollectionNode *)collectionNode numberOfItemsInSection:(NSInteger)section
|
||||
- (NSInteger)collectionNode:(ASCollectionNode *)collectionNode numberOfItemsInSection:(NSInteger)section
|
||||
{
|
||||
return [_sections[section] count];
|
||||
}
|
||||
|
||||
@ -39,6 +39,8 @@ static const CGFloat kInnerPadding = 10.0f;
|
||||
|
||||
@implementation HorizontalScrollCellNode
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
- (instancetype)initWithElementSize:(CGSize)size
|
||||
{
|
||||
if (!(self = [super init]))
|
||||
@ -46,11 +48,16 @@ static const CGFloat kInnerPadding = 10.0f;
|
||||
|
||||
_elementSize = size;
|
||||
|
||||
// the containing table uses -nodeForRowAtIndexPath (rather than -nodeBlockForRowAtIndexPath),
|
||||
// so this init method will always be run on the main thread (thus it is safe to do UIKit things).
|
||||
UICollectionViewFlowLayout *flowLayout = [[UICollectionViewFlowLayout alloc] init];
|
||||
flowLayout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
|
||||
flowLayout.itemSize = _elementSize;
|
||||
flowLayout.minimumInteritemSpacing = kInnerPadding;
|
||||
|
||||
_collectionNode = [[ASCollectionNode alloc] initWithCollectionViewLayout:flowLayout];
|
||||
_collectionNode.delegate = self;
|
||||
_collectionNode.dataSource = self;
|
||||
[self addSubnode:_collectionNode];
|
||||
|
||||
// hairline cell separator
|
||||
@ -61,40 +68,6 @@ static const CGFloat kInnerPadding = 10.0f;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)didLoad
|
||||
{
|
||||
[super didLoad];
|
||||
|
||||
_collectionNode.view.asyncDelegate = self;
|
||||
_collectionNode.view.asyncDataSource = self;
|
||||
}
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
- (ASCellNodeBlock)collectionView:(ASCollectionView *)collectionView nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
CGSize elementSize = _elementSize;
|
||||
return ^{
|
||||
RandomCoreGraphicsNode *elementNode = [[RandomCoreGraphicsNode alloc] init];
|
||||
elementNode.style.preferredSize = elementSize;
|
||||
return elementNode;
|
||||
};
|
||||
}
|
||||
|
||||
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||
{
|
||||
CGSize collectionNodeSize = CGSizeMake(constrainedSize.max.width, _elementSize.height);
|
||||
_collectionNode.style.preferredSize = collectionNodeSize;
|
||||
|
||||
ASInsetLayoutSpec *insetSpec = [[ASInsetLayoutSpec alloc] init];
|
||||
insetSpec.insets = UIEdgeInsetsMake(kOuterPadding, 0.0, kOuterPadding, 0.0);
|
||||
insetSpec.child = _collectionNode;
|
||||
return insetSpec;
|
||||
}
|
||||
|
||||
// With box model, you don't need to override this method, unless you want to add custom logic.
|
||||
- (void)layout
|
||||
{
|
||||
@ -107,4 +80,34 @@ static const CGFloat kInnerPadding = 10.0f;
|
||||
_divider.frame = CGRectMake(0.0f, 0.0f, self.calculatedSize.width, pixelHeight);
|
||||
}
|
||||
|
||||
- (ASLayoutSpec *)layoutSpecThatFits:(ASSizeRange)constrainedSize
|
||||
{
|
||||
CGSize collectionNodeSize = CGSizeMake(constrainedSize.max.width, _elementSize.height);
|
||||
_collectionNode.style.preferredSize = collectionNodeSize;
|
||||
|
||||
ASInsetLayoutSpec *insetSpec = [[ASInsetLayoutSpec alloc] init];
|
||||
insetSpec.insets = UIEdgeInsetsMake(kOuterPadding, 0.0, kOuterPadding, 0.0);
|
||||
insetSpec.child = _collectionNode;
|
||||
|
||||
return insetSpec;
|
||||
}
|
||||
|
||||
#pragma mark - ASCollectionNode
|
||||
|
||||
- (NSInteger)collectionNode:(ASCollectionNode *)collectionNode numberOfItemsInSection:(NSInteger)section
|
||||
{
|
||||
return 5;
|
||||
}
|
||||
|
||||
- (ASCellNodeBlock)collectionNode:(ASCollectionNode *)collectionNode nodeBlockForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
CGSize elementSize = _elementSize;
|
||||
|
||||
return ^{
|
||||
RandomCoreGraphicsNode *elementNode = [[RandomCoreGraphicsNode alloc] init];
|
||||
elementNode.style.preferredSize = elementSize;
|
||||
return elementNode;
|
||||
};
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -34,13 +34,13 @@
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (!(self = [super initWithNode:_tableNode]))
|
||||
return nil;
|
||||
|
||||
_tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];
|
||||
_tableNode.dataSource = self;
|
||||
_tableNode.delegate = self;
|
||||
|
||||
|
||||
if (!(self = [super initWithNode:_tableNode]))
|
||||
return nil;
|
||||
|
||||
self.title = @"Horizontal Scrolling Gradients";
|
||||
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRedo
|
||||
target:self
|
||||
@ -61,14 +61,14 @@
|
||||
[_tableNode reloadData];
|
||||
}
|
||||
|
||||
#pragma mark - ASTableView.
|
||||
#pragma mark - ASTableNode
|
||||
|
||||
- (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (ASCellNode *)tableNode:(ASTableNode *)tableNode nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
return [[HorizontalScrollCellNode alloc] initWithElementSize:CGSizeMake(100, 100)];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
- (NSInteger)tableNode:(ASTableNode *)tableNode numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
@ -15,8 +15,8 @@
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
|
||||
@interface ViewController : UIViewController
|
||||
@interface ViewController : ASViewController
|
||||
|
||||
@end
|
||||
|
||||
@ -24,13 +24,13 @@
|
||||
#import "KittenNode.h"
|
||||
|
||||
|
||||
static const NSInteger kLitterSize = 20; // intial number of kitten cells in ASTableView
|
||||
static const NSInteger kLitterBatchSize = 10; // number of kitten cells to add to ASTableView
|
||||
static const NSInteger kMaxLitterSize = 100; // max number of kitten cells allowed in ASTableView
|
||||
static const NSInteger kLitterSize = 20; // intial number of kitten cells in ASTableNode
|
||||
static const NSInteger kLitterBatchSize = 10; // number of kitten cells to add to ASTableNode
|
||||
static const NSInteger kMaxLitterSize = 100; // max number of kitten cells allowed in ASTableNode
|
||||
|
||||
@interface ViewController () <ASTableViewDataSource, ASTableViewDelegate>
|
||||
@interface ViewController () <ASTableDataSource, ASTableDelegate>
|
||||
{
|
||||
ASTableView *_tableView;
|
||||
ASTableNode *_tableNode;
|
||||
|
||||
// array of boxed CGSizes corresponding to placekitten.com kittens
|
||||
NSMutableArray *_kittenDataSource;
|
||||
@ -47,32 +47,40 @@ static const NSInteger kMaxLitterSize = 100; // max number of kitten cell
|
||||
|
||||
@implementation ViewController
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark UIViewController.
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
if (!(self = [super init]))
|
||||
return nil;
|
||||
_tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];
|
||||
_tableNode.dataSource = self;
|
||||
_tableNode.delegate = self;
|
||||
|
||||
_tableView = [[ASTableView alloc] initWithFrame:CGRectZero style:UITableViewStylePlain];
|
||||
_tableView.separatorStyle = UITableViewCellSeparatorStyleNone; // KittenNode has its own separator
|
||||
_tableView.asyncDataSource = self;
|
||||
_tableView.asyncDelegate = self;
|
||||
if (!(self = [super initWithNode:_tableNode]))
|
||||
return nil;
|
||||
|
||||
_tableNode.view.separatorStyle = UITableViewCellSeparatorStyleNone; // KittenNode has its own separator
|
||||
|
||||
// populate our "data source" with some random kittens
|
||||
_kittenDataSource = [self createLitterWithSize:kLitterSize];
|
||||
|
||||
_blurbNodeIndexPath = [NSIndexPath indexPathForItem:0 inSection:0];
|
||||
|
||||
self.title = @"Kittens";
|
||||
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemEdit
|
||||
target:self
|
||||
action:@selector(toggleEditingMode)];
|
||||
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
[self.node addSubnode:_tableNode];
|
||||
}
|
||||
|
||||
#pragma mark - Data Model
|
||||
|
||||
- (NSMutableArray *)createLitterWithSize:(NSInteger)litterSize
|
||||
{
|
||||
NSMutableArray *kittens = [NSMutableArray arrayWithCapacity:litterSize];
|
||||
@ -95,36 +103,21 @@ static const NSInteger kMaxLitterSize = 100; // max number of kitten cell
|
||||
_kittenDataSource = kittenDataSource;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
[self.view addSubview:_tableView];
|
||||
}
|
||||
|
||||
- (void)viewWillLayoutSubviews
|
||||
{
|
||||
_tableView.frame = self.view.bounds;
|
||||
}
|
||||
|
||||
- (void)toggleEditingMode
|
||||
{
|
||||
[_tableView setEditing:!_tableView.editing animated:YES];
|
||||
[_tableNode.view setEditing:!_tableNode.view.editing animated:YES];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark -
|
||||
#pragma mark ASTableView.
|
||||
#pragma mark - ASTableNode
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (NSInteger)tableNode:(ASTableNode *)tableNode numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
[_tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
// Assume only kitten nodes are selectable (see -tableView:shouldHighlightRowAtIndexPath:).
|
||||
KittenNode *node = (KittenNode *)[_tableView nodeForRowAtIndexPath:indexPath];
|
||||
[node toggleImageEnlargement];
|
||||
// blurb node + kLitterSize kitties
|
||||
return 1 + _kittenDataSource.count;
|
||||
}
|
||||
|
||||
- (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (ASCellNode *)tableNode:(ASTableNode *)tableNode nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
// special-case the first row
|
||||
if ([_blurbNodeIndexPath compare:indexPath] == NSOrderedSame) {
|
||||
@ -137,34 +130,23 @@ static const NSInteger kMaxLitterSize = 100; // max number of kitten cell
|
||||
return node;
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
- (void)tableNode:(ASTableNode *)tableNode didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
// blurb node + kLitterSize kitties
|
||||
return 1 + _kittenDataSource.count;
|
||||
[_tableNode deselectRowAtIndexPath:indexPath animated:YES];
|
||||
|
||||
// Assume only kitten nodes are selectable (see -tableNode:shouldHighlightRowAtIndexPath:).
|
||||
KittenNode *node = (KittenNode *)[_tableNode nodeForRowAtIndexPath:indexPath];
|
||||
|
||||
[node toggleImageEnlargement];
|
||||
}
|
||||
|
||||
- (BOOL)tableView:(UITableView *)tableView shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (BOOL)tableNode:(ASTableNode *)tableNode shouldHighlightRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
// Enable selection for kitten nodes
|
||||
return [_blurbNodeIndexPath compare:indexPath] != NSOrderedSame;
|
||||
}
|
||||
|
||||
- (void)tableViewLockDataSource:(ASTableView *)tableView
|
||||
{
|
||||
self.dataSourceLocked = YES;
|
||||
}
|
||||
|
||||
- (void)tableViewUnlockDataSource:(ASTableView *)tableView
|
||||
{
|
||||
self.dataSourceLocked = NO;
|
||||
}
|
||||
|
||||
- (BOOL)shouldBatchFetchForTableView:(UITableView *)tableView
|
||||
{
|
||||
return _kittenDataSource.count < kMaxLitterSize;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView willBeginBatchFetchWithContext:(ASBatchContext *)context
|
||||
- (void)tableNode:(ASTableNode *)tableNode willBeginBatchFetchWithContext:(nonnull ASBatchContext *)context
|
||||
{
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
|
||||
// populate a new array of random-sized kittens
|
||||
@ -181,24 +163,30 @@ static const NSInteger kMaxLitterSize = 100; // max number of kitten cell
|
||||
|
||||
// add new kittens to the data source & notify table of new indexpaths
|
||||
[_kittenDataSource addObjectsFromArray:moarKittens];
|
||||
[tableView insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
|
||||
[tableNode insertRowsAtIndexPaths:indexPaths withRowAnimation:UITableViewRowAnimationFade];
|
||||
|
||||
[context completeBatchFetching:YES];
|
||||
});
|
||||
}
|
||||
|
||||
- (BOOL)shouldBatchFetchForTableNode:(ASTableNode *)tableNode
|
||||
{
|
||||
return _kittenDataSource.count < kMaxLitterSize;
|
||||
}
|
||||
|
||||
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
// Enable editing for Kitten nodes
|
||||
return [_blurbNodeIndexPath compare:indexPath] != NSOrderedSame;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
|
||||
forRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
if (editingStyle == UITableViewCellEditingStyleDelete) {
|
||||
// Assume only kitten nodes are editable (see -tableView:canEditRowAtIndexPath:).
|
||||
[_kittenDataSource removeObjectAtIndex:indexPath.row - 1];
|
||||
[_tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
[_tableNode deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <AsyncDisplayKit/AsyncDisplayKit.h>
|
||||
|
||||
@interface ViewController : UIViewController
|
||||
@interface ViewController : ASViewController
|
||||
@end
|
||||
|
||||
@ -24,45 +24,47 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
@interface ViewController () <ASTableViewDataSource, ASTableViewDelegate>
|
||||
@interface ViewController () <ASTableDataSource, ASTableDelegate>
|
||||
|
||||
@property (nonatomic, strong) ASTableView *tableView;
|
||||
@property (nonatomic, strong) ASTableNode *tableNode;
|
||||
@property (nonatomic, strong) NSMutableArray *socialAppDataSource;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark - Lifecycle
|
||||
|
||||
@implementation ViewController
|
||||
|
||||
- (instancetype)init
|
||||
{
|
||||
self = [super init];
|
||||
_tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];
|
||||
|
||||
self = [super initWithNode:_tableNode];
|
||||
|
||||
if (self) {
|
||||
|
||||
_tableNode.delegate = self;
|
||||
_tableNode.dataSource = self;
|
||||
_tableNode.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
|
||||
self.title = @"Timeline";
|
||||
|
||||
[self createSocialAppDataSource];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
_tableView.asyncDataSource = nil;
|
||||
_tableView.asyncDelegate = nil;
|
||||
}
|
||||
|
||||
- (void)viewDidLoad
|
||||
{
|
||||
[super viewDidLoad];
|
||||
|
||||
self.tableView = [[ASTableView alloc] initWithFrame:self.view.bounds style:UITableViewStylePlain];
|
||||
self.tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
|
||||
self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; // SocialAppNode has its own separator
|
||||
self.tableView.asyncDataSource = self;
|
||||
self.tableView.asyncDelegate = self;
|
||||
[self.view addSubview:self.tableView];
|
||||
|
||||
// SocialAppNode has its own separator
|
||||
self.tableNode.view.separatorStyle = UITableViewCellSeparatorStyleNone;
|
||||
}
|
||||
|
||||
#pragma mark - Data Model
|
||||
|
||||
- (void)createSocialAppDataSource
|
||||
{
|
||||
_socialAppDataSource = [[NSMutableArray alloc] init];
|
||||
@ -116,9 +118,9 @@
|
||||
[_socialAppDataSource addObject:newPost];
|
||||
}
|
||||
|
||||
#pragma mark - ASTableView
|
||||
#pragma mark - ASTableNode
|
||||
|
||||
- (ASCellNodeBlock)tableView:(ASTableView *)tableView nodeBlockForRowAtIndexPath:(nonnull NSIndexPath *)indexPath
|
||||
- (ASCellNodeBlock)tableNode:(ASTableNode *)tableNode nodeBlockForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
Post *post = self.socialAppDataSource[indexPath.row];
|
||||
return ^{
|
||||
@ -126,14 +128,14 @@
|
||||
};
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
- (NSInteger)tableNode:(ASTableNode *)tableNode numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return self.socialAppDataSource.count;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (void)tableNode:(ASTableNode *)tableNode didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
PostNode *postNode = (PostNode *)[_tableView nodeForRowAtIndexPath:indexPath];
|
||||
PostNode *postNode = (PostNode *)[_tableNode nodeForRowAtIndexPath:indexPath];
|
||||
Post *post = self.socialAppDataSource[indexPath.row];
|
||||
|
||||
BOOL shouldRasterize = postNode.shouldRasterizeDescendants;
|
||||
@ -142,7 +144,7 @@
|
||||
|
||||
NSLog(@"%@ rasterization for %@'s post: %@", shouldRasterize ? @"Enabling" : @"Disabling", post.name, postNode);
|
||||
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:YES];
|
||||
[tableNode deselectRowAtIndexPath:indexPath animated:YES];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -47,12 +47,12 @@ final class ViewController: ASViewController, ASTableDataSource, ASTableDelegate
|
||||
fatalError("storyboards are incompatible with truth and beauty")
|
||||
}
|
||||
|
||||
// MARK: ASTableView data source and delegate.
|
||||
// MARK: ASTableNode data source and delegate.
|
||||
|
||||
func tableView(tableView: ASTableView, nodeForRowAtIndexPath indexPath: NSIndexPath) -> ASCellNode {
|
||||
func tableNode(tableNode: ASTableNode, nodeForRowAtIndexPath indexPath: NSIndexPath) -> ASCellNode {
|
||||
// Should read the row count directly from table view but
|
||||
// https://github.com/facebook/AsyncDisplayKit/issues/1159
|
||||
let rowCount = self.tableView(tableView, numberOfRowsInSection: 0)
|
||||
let rowCount = self.tableNode(tableNode, numberOfRowsInSection: 0)
|
||||
|
||||
if state.fetchingMore && indexPath.row == rowCount - 1 {
|
||||
return TailLoadingCellNode()
|
||||
@ -64,11 +64,11 @@ final class ViewController: ASViewController, ASTableDataSource, ASTableDelegate
|
||||
return node
|
||||
}
|
||||
|
||||
func numberOfSectionsInTableView(tableView: UITableView) -> Int {
|
||||
func numberOfSectionsInTableNode(tableNode: ASTableNode) -> Int {
|
||||
return 1
|
||||
}
|
||||
|
||||
func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
func tableNode(tableNode: ASTableNode, numberOfRowsInSection section: Int) -> Int {
|
||||
var count = state.itemCount
|
||||
if state.fetchingMore {
|
||||
count += 1
|
||||
@ -76,7 +76,7 @@ final class ViewController: ASViewController, ASTableDataSource, ASTableDelegate
|
||||
return count
|
||||
}
|
||||
|
||||
func tableView(tableView: ASTableView, willBeginBatchFetchWithContext context: ASBatchContext) {
|
||||
func tableNode(tableNode: ASTableNode, willBeginBatchFetchWithContext context: ASBatchContext) {
|
||||
/// This call will come in on a background thread. Switch to main
|
||||
/// to add our spinner, then fire off our fetch.
|
||||
dispatch_async(dispatch_get_main_queue()) {
|
||||
@ -95,33 +95,33 @@ final class ViewController: ASViewController, ASTableDataSource, ASTableDelegate
|
||||
}
|
||||
|
||||
private func renderDiff(oldState: State) {
|
||||
let tableView = tableNode.view
|
||||
tableView.beginUpdates()
|
||||
|
||||
// Add or remove items
|
||||
let rowCountChange = state.itemCount - oldState.itemCount
|
||||
if rowCountChange > 0 {
|
||||
let indexPaths = (oldState.itemCount..<state.itemCount).map { index in
|
||||
NSIndexPath(forRow: index, inSection: 0)
|
||||
|
||||
self.tableNode.performBatchUpdates({
|
||||
|
||||
// Add or remove items
|
||||
let rowCountChange = state.itemCount - oldState.itemCount
|
||||
if rowCountChange > 0 {
|
||||
let indexPaths = (oldState.itemCount..<state.itemCount).map { index in
|
||||
NSIndexPath(forRow: index, inSection: 0)
|
||||
}
|
||||
tableNode.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .None)
|
||||
} else if rowCountChange < 0 {
|
||||
assertionFailure("Deleting rows is not implemented. YAGNI.")
|
||||
}
|
||||
tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .None)
|
||||
} else if rowCountChange < 0 {
|
||||
assertionFailure("Deleting rows is not implemented. YAGNI.")
|
||||
}
|
||||
|
||||
// Add or remove spinner.
|
||||
if state.fetchingMore != oldState.fetchingMore {
|
||||
if state.fetchingMore {
|
||||
// Add spinner.
|
||||
let spinnerIndexPath = NSIndexPath(forRow: state.itemCount, inSection: 0)
|
||||
tableView.insertRowsAtIndexPaths([ spinnerIndexPath ], withRowAnimation: .None)
|
||||
} else {
|
||||
// Remove spinner.
|
||||
let spinnerIndexPath = NSIndexPath(forRow: oldState.itemCount, inSection: 0)
|
||||
tableView.deleteRowsAtIndexPaths([ spinnerIndexPath ], withRowAnimation: .None)
|
||||
// Add or remove spinner.
|
||||
if state.fetchingMore != oldState.fetchingMore {
|
||||
if state.fetchingMore {
|
||||
// Add spinner.
|
||||
let spinnerIndexPath = NSIndexPath(forRow: state.itemCount, inSection: 0)
|
||||
tableNode.insertRowsAtIndexPaths([ spinnerIndexPath ], withRowAnimation: .None)
|
||||
} else {
|
||||
// Remove spinner.
|
||||
let spinnerIndexPath = NSIndexPath(forRow: oldState.itemCount, inSection: 0)
|
||||
tableNode.deleteRowsAtIndexPaths([ spinnerIndexPath ], withRowAnimation: .None)
|
||||
}
|
||||
}
|
||||
}
|
||||
tableView.endUpdatesAnimated(false, completion: nil)
|
||||
}, completion:nil)
|
||||
}
|
||||
|
||||
/// (Pretend) fetches some new items and calls the
|
||||
|
||||
@ -21,7 +21,7 @@
|
||||
* This ASCellNode contains an ASTableNode. It intelligently interacts with a containing ASCollectionView,
|
||||
* to preload and clean up contents as the user scrolls around both vertically and horizontally — in a way that minimizes memory usage.
|
||||
*/
|
||||
@interface GradientTableNode : ASCellNode <ASTableViewDelegate, ASTableViewDataSource>
|
||||
@interface GradientTableNode : ASCellNode
|
||||
|
||||
- (instancetype)initWithElementSize:(CGSize)size;
|
||||
|
||||
|
||||
@ -24,7 +24,8 @@
|
||||
#import <AsyncDisplayKit/ASStackLayoutSpec.h>
|
||||
#import <AsyncDisplayKit/ASInsetLayoutSpec.h>
|
||||
|
||||
@interface GradientTableNode ()
|
||||
|
||||
@interface GradientTableNode () <ASTableDelegate, ASTableDataSource>
|
||||
{
|
||||
ASTableNode *_tableNode;
|
||||
CGSize _elementSize;
|
||||
@ -43,40 +44,37 @@
|
||||
_elementSize = size;
|
||||
|
||||
_tableNode = [[ASTableNode alloc] initWithStyle:UITableViewStylePlain];
|
||||
_tableNode.delegate = self;
|
||||
_tableNode.dataSource = self;
|
||||
|
||||
ASRangeTuningParameters rangeTuningParameters;
|
||||
rangeTuningParameters.leadingBufferScreenfuls = 1.0;
|
||||
rangeTuningParameters.trailingBufferScreenfuls = 0.5;
|
||||
[_tableNode setTuningParameters:rangeTuningParameters forRangeType:ASLayoutRangeTypeDisplay];
|
||||
|
||||
[self addSubnode:_tableNode];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)didLoad
|
||||
{
|
||||
[super didLoad];
|
||||
_tableNode.view.asyncDelegate = self;
|
||||
_tableNode.view.asyncDataSource = self;
|
||||
|
||||
ASRangeTuningParameters rangeTuningParameters;
|
||||
rangeTuningParameters.leadingBufferScreenfuls = 1.0;
|
||||
rangeTuningParameters.trailingBufferScreenfuls = 0.5;
|
||||
[_tableNode.view setTuningParameters:rangeTuningParameters forRangeType:ASLayoutRangeTypeDisplay];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
- (NSInteger)tableNode:(ASTableNode *)tableNode numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return 100;
|
||||
}
|
||||
|
||||
- (ASCellNode *)tableView:(ASTableView *)tableView nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (ASCellNode *)tableNode:(ASTableNode *)tableNode nodeForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RandomCoreGraphicsNode *elementNode = [[RandomCoreGraphicsNode alloc] init];
|
||||
elementNode.style.preferredSize = _elementSize;
|
||||
elementNode.indexPath = [NSIndexPath indexPathForRow:indexPath.row inSection:_pageNumber];
|
||||
|
||||
return elementNode;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
- (void)tableNode:(ASTableNode *)tableNode didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
[tableView deselectRowAtIndexPath:indexPath animated:NO];
|
||||
[_tableNode.view reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
|
||||
[tableNode deselectRowAtIndexPath:indexPath animated:NO];
|
||||
[_tableNode reloadRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];
|
||||
}
|
||||
|
||||
- (void)layout
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user