From 0b7dfcc54dba91bbc1a6968dd6c085274b143485 Mon Sep 17 00:00:00 2001 From: Hannah Troisi Date: Mon, 24 Oct 2016 17:14:28 -0700 Subject: [PATCH] [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 --- .../ASViewController/Sample/ViewController.m | 2 +- .../OverviewASCollectionNode.m | 6 +- .../Node Containers/OverviewASTableNode.m | 4 +- .../Sample/OverviewComponentsViewController.h | 4 +- .../Sample/OverviewComponentsViewController.m | 54 ++++++--- .../Sample/ViewController.m | 114 ++++++++---------- .../CustomCollectionView/Sample/AppDelegate.m | 2 +- .../Sample/ViewController.m | 34 +++--- .../Sample/HorizontalScrollCellNode.mm | 71 +++++------ .../Sample/ViewController.m | 14 +-- examples/Kittens/Sample/ViewController.h | 4 +- examples/Kittens/Sample/ViewController.m | 106 ++++++++-------- .../SocialAppLayout/Sample/ViewController.h | 4 +- .../SocialAppLayout/Sample/ViewController.m | 48 ++++---- examples/Swift/Sample/ViewController.swift | 60 ++++----- .../Sample/GradientTableNode.h | 2 +- .../Sample/GradientTableNode.mm | 34 +++--- 17 files changed, 275 insertions(+), 288 deletions(-) diff --git a/examples/ASViewController/Sample/ViewController.m b/examples/ASViewController/Sample/ViewController.m index b7014b6c8c..2b3cb1d229 100644 --- a/examples/ASViewController/Sample/ViewController.m +++ b/examples/ASViewController/Sample/ViewController.m @@ -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]; } diff --git a/examples/AsyncDisplayKitOverview/Sample/Node Containers/OverviewASCollectionNode.m b/examples/AsyncDisplayKitOverview/Sample/Node Containers/OverviewASCollectionNode.m index d58b6862a5..78c8615ede 100644 --- a/examples/AsyncDisplayKitOverview/Sample/Node Containers/OverviewASCollectionNode.m +++ b/examples/AsyncDisplayKitOverview/Sample/Node Containers/OverviewASCollectionNode.m @@ -53,12 +53,12 @@ #pragma mark - -- (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)); } diff --git a/examples/AsyncDisplayKitOverview/Sample/Node Containers/OverviewASTableNode.m b/examples/AsyncDisplayKitOverview/Sample/Node Containers/OverviewASTableNode.m index 3d1e65ddba..1a94fdbf84 100644 --- a/examples/AsyncDisplayKitOverview/Sample/Node Containers/OverviewASTableNode.m +++ b/examples/AsyncDisplayKitOverview/Sample/Node Containers/OverviewASTableNode.m @@ -51,12 +51,12 @@ #pragma mark - -- (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]; diff --git a/examples/AsyncDisplayKitOverview/Sample/OverviewComponentsViewController.h b/examples/AsyncDisplayKitOverview/Sample/OverviewComponentsViewController.h index 880cf78a58..9e838b4fba 100644 --- a/examples/AsyncDisplayKitOverview/Sample/OverviewComponentsViewController.h +++ b/examples/AsyncDisplayKitOverview/Sample/OverviewComponentsViewController.h @@ -17,7 +17,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#import +#import @protocol ASLayoutSpecListEntry @@ -27,7 +27,7 @@ @end -@interface OverviewComponentsViewController : UIViewController +@interface OverviewComponentsViewController : ASViewController @end diff --git a/examples/AsyncDisplayKitOverview/Sample/OverviewComponentsViewController.m b/examples/AsyncDisplayKitOverview/Sample/OverviewComponentsViewController.m index 585c4c35f2..c343d74a65 100644 --- a/examples/AsyncDisplayKitOverview/Sample/OverviewComponentsViewController.m +++ b/examples/AsyncDisplayKitOverview/Sample/OverviewComponentsViewController.m @@ -31,12 +31,15 @@ typedef ASLayoutSpec *(^OverviewDisplayNodeSizeThatFitsBlock)(ASSizeRange constrainedSize); + #pragma mark - OverviewDisplayNodeWithSizeBlock @interface OverviewDisplayNodeWithSizeBlock : ASDisplayNode + @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)self; + _tableNode.dataSource = (id)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)self; - _tableNode.dataSource = (id)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 - -- (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 *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]; diff --git a/examples/CatDealsCollectionView/Sample/ViewController.m b/examples/CatDealsCollectionView/Sample/ViewController.m index 4cec349673..8726968ef4 100644 --- a/examples/CatDealsCollectionView/Sample/ViewController.m +++ b/examples/CatDealsCollectionView/Sample/ViewController.m @@ -29,7 +29,7 @@ static const NSInteger kBatchSize = 20; static const CGFloat kHorizontalSectionPadding = 10.0f; static const CGFloat kVerticalSectionPadding = 20.0f; -@interface ViewController () +@interface ViewController () { 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 diff --git a/examples/CustomCollectionView/Sample/AppDelegate.m b/examples/CustomCollectionView/Sample/AppDelegate.m index 853bf6e8bc..c0769e5d5a 100644 --- a/examples/CustomCollectionView/Sample/AppDelegate.m +++ b/examples/CustomCollectionView/Sample/AppDelegate.m @@ -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; diff --git a/examples/CustomCollectionView/Sample/ViewController.m b/examples/CustomCollectionView/Sample/ViewController.m index a7fe524811..5d070ebcd6 100644 --- a/examples/CustomCollectionView/Sample/ViewController.m +++ b/examples/CustomCollectionView/Sample/ViewController.m @@ -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]; } diff --git a/examples/HorizontalWithinVerticalScrolling/Sample/HorizontalScrollCellNode.mm b/examples/HorizontalWithinVerticalScrolling/Sample/HorizontalScrollCellNode.mm index e070c4fbe9..9f2f355e9a 100644 --- a/examples/HorizontalWithinVerticalScrolling/Sample/HorizontalScrollCellNode.mm +++ b/examples/HorizontalWithinVerticalScrolling/Sample/HorizontalScrollCellNode.mm @@ -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 diff --git a/examples/HorizontalWithinVerticalScrolling/Sample/ViewController.m b/examples/HorizontalWithinVerticalScrolling/Sample/ViewController.m index 56ba5e22ab..876775f35c 100644 --- a/examples/HorizontalWithinVerticalScrolling/Sample/ViewController.m +++ b/examples/HorizontalWithinVerticalScrolling/Sample/ViewController.m @@ -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; } diff --git a/examples/Kittens/Sample/ViewController.h b/examples/Kittens/Sample/ViewController.h index fc52c022f2..db689fe324 100644 --- a/examples/Kittens/Sample/ViewController.h +++ b/examples/Kittens/Sample/ViewController.h @@ -15,8 +15,8 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#import +#import -@interface ViewController : UIViewController +@interface ViewController : ASViewController @end diff --git a/examples/Kittens/Sample/ViewController.m b/examples/Kittens/Sample/ViewController.m index b4f0ad01b0..6b2e4b5058 100644 --- a/examples/Kittens/Sample/ViewController.m +++ b/examples/Kittens/Sample/ViewController.m @@ -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 () +@interface ViewController () { - 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]; } } diff --git a/examples/SocialAppLayout/Sample/ViewController.h b/examples/SocialAppLayout/Sample/ViewController.h index 40359e2f0e..bfb359c6b5 100644 --- a/examples/SocialAppLayout/Sample/ViewController.h +++ b/examples/SocialAppLayout/Sample/ViewController.h @@ -15,7 +15,7 @@ // CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // -#import +#import -@interface ViewController : UIViewController +@interface ViewController : ASViewController @end diff --git a/examples/SocialAppLayout/Sample/ViewController.m b/examples/SocialAppLayout/Sample/ViewController.m index 492861c01b..71458a1ae8 100644 --- a/examples/SocialAppLayout/Sample/ViewController.m +++ b/examples/SocialAppLayout/Sample/ViewController.m @@ -24,45 +24,47 @@ #include -@interface ViewController () +@interface ViewController () -@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 diff --git a/examples/Swift/Sample/ViewController.swift b/examples/Swift/Sample/ViewController.swift index 0982081c0a..66ed35391b 100644 --- a/examples/Swift/Sample/ViewController.swift +++ b/examples/Swift/Sample/ViewController.swift @@ -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.. 0 { + let indexPaths = (oldState.itemCount.. +@interface GradientTableNode : ASCellNode - (instancetype)initWithElementSize:(CGSize)size; diff --git a/examples/VerticalWithinHorizontalScrolling/Sample/GradientTableNode.mm b/examples/VerticalWithinHorizontalScrolling/Sample/GradientTableNode.mm index 907fa16a4e..8e6c884f11 100644 --- a/examples/VerticalWithinHorizontalScrolling/Sample/GradientTableNode.mm +++ b/examples/VerticalWithinHorizontalScrolling/Sample/GradientTableNode.mm @@ -24,7 +24,8 @@ #import #import -@interface GradientTableNode () + +@interface GradientTableNode () { 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