[Umbrella] ASCollectionView -> ASCollectionNode Migration, Separate Index Spaces (#2372)

* Separate dataSource & UIKit index spaces

Beef up our supplementary node support

Make the API way better

Go nuts

Add a unit test for UICollectionView's handling of reloadData inside batch updates

Wrap indexPathForNode: in a cache

Convert index paths in delegate methods

Go back on table view

Put collection view back

Switch up the API

Move most ASCollectionView API to ASCollectionNode

Move most table logic over to ASTableNode

Do the things

More conversion work

Keep on keepin' on

Get table view delegate API done

More porting

Simplify

Clear the delegate

More cleanup

Move more stuff around

Remove pointless file

Re-add some API

Put back more API

Use the right flag

* Some cleanup

* Remove incorrect comment

* Tweak the API

* Put back a couple methods

* update example projects (note: ASCollectionView deprecation warnings expected)

* change reloadDataWithCompletion:nil --> reloadData

* Clean up rebase

* Make deprecated numberOfItemsInSection methods optional

* Use the right flag

* Address nits

* update ASDKTube, ASDKgram & ASViewController examples
This commit is contained in:
Adlai Holler
2016-10-14 17:21:16 -07:00
committed by GitHub
parent fb768683bc
commit c2ea7cfeac
50 changed files with 3448 additions and 1122 deletions

View File

@@ -0,0 +1,267 @@
//
// ASCollectionView+Undeprecated.h
// AsyncDisplayKit
//
// Created by Adlai Holler on 10/10/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import <AsyncDisplayKit/AsyncDisplayKit.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Currently our public collection API is on @c ASCollectionNode and the @c ASCollectionView
* API is deprecated, but the implementations still live in the view.
*
* This category lets us avoid deprecation warnings everywhere internally.
* In the future, the @c ASCollectionView public API will be eliminated and so will this file.
*/
@interface ASCollectionView (Undeprecated)
/**
* Initializes an ASCollectionView
*
* @discussion Initializes and returns a newly allocated collection view object with the specified layout.
*
* @param layout The layout object to use for organizing items. The collection view stores a strong reference to the specified object. Must not be nil.
*/
- (instancetype)initWithCollectionViewLayout:(UICollectionViewLayout *)layout;
/**
* Initializes an ASCollectionView
*
* @discussion Initializes and returns a newly allocated collection view object with the specified frame and layout.
*
* @param frame The frame rectangle for the collection view, measured in points. The origin of the frame is relative to the superview in which you plan to add it. This frame is passed to the superclass during initialization.
* @param layout The layout object to use for organizing items. The collection view stores a strong reference to the specified object. Must not be nil.
*/
- (instancetype)initWithFrame:(CGRect)frame collectionViewLayout:(UICollectionViewLayout *)layout;
/**
* Tuning parameters for a range type in full mode.
*
* @param rangeType The range type to get the tuning parameters for.
*
* @return A tuning parameter value for the given range type in full mode.
*
* @see ASLayoutRangeMode
* @see ASLayoutRangeType
*/
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType AS_WARN_UNUSED_RESULT;
/**
* Set the tuning parameters for a range type in full mode.
*
* @param tuningParameters The tuning parameters to store for a range type.
* @param rangeType The range type to set the tuning parameters for.
*
* @see ASLayoutRangeMode
* @see ASLayoutRangeType
*/
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType;
/**
* Tuning parameters for a range type in the specified mode.
*
* @param rangeMode The range mode to get the running parameters for.
* @param rangeType The range type to get the tuning parameters for.
*
* @return A tuning parameter value for the given range type in the given mode.
*
* @see ASLayoutRangeMode
* @see ASLayoutRangeType
*/
- (ASRangeTuningParameters)tuningParametersForRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType AS_WARN_UNUSED_RESULT;
/**
* Set the tuning parameters for a range type in the specified mode.
*
* @param tuningParameters The tuning parameters to store for a range type.
* @param rangeMode The range mode to set the running parameters for.
* @param rangeType The range type to set the tuning parameters for.
*
* @see ASLayoutRangeMode
* @see ASLayoutRangeType
*/
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType;
/**
* Perform a batch of updates asynchronously, optionally disabling all animations in the batch. This method must be called from the main thread.
* The asyncDataSource must be updated to reflect the changes before the update block completes.
*
* @param animated NO to disable animations for this batch
* @param updates The block that performs the relevant insert, delete, reload, or move operations.
* @param completion A completion handler block to execute when all of the operations are finished. This block takes a single
* Boolean parameter that contains the value YES if all of the related animations completed successfully or
* NO if they were interrupted. This parameter may be nil. If supplied, the block is run on the main thread.
*/
- (void)performBatchAnimated:(BOOL)animated updates:(nullable __attribute((noescape)) void (^)())updates completion:(nullable void (^)(BOOL finished))completion;
/**
* Perform a batch of updates asynchronously. This method must be called from the main thread.
* The asyncDataSource must be updated to reflect the changes before update block completes.
*
* @param updates The block that performs the relevant insert, delete, reload, or move operations.
* @param completion A completion handler block to execute when all of the operations are finished. This block takes a single
* Boolean parameter that contains the value YES if all of the related animations completed successfully or
* NO if they were interrupted. This parameter may be nil. If supplied, the block is run on the main thread.
*/
- (void)performBatchUpdates:(nullable __attribute((noescape)) void (^)())updates completion:(nullable void (^)(BOOL finished))completion;
/**
* Reload everything from scratch, destroying the working range and all cached nodes.
*
* @param completion block to run on completion of asynchronous loading or nil. If supplied, the block is run on
* the main thread.
* @warning This method is substantially more expensive than UICollectionView's version.
*/
- (void)reloadDataWithCompletion:(nullable void (^)())completion;
/**
* Reload everything from scratch, destroying the working range and all cached nodes.
*
* @warning This method is substantially more expensive than UICollectionView's version.
*/
- (void)reloadData;
/**
* Reload everything from scratch entirely on the main thread, destroying the working range and all cached nodes.
*
* @warning This method is substantially more expensive than UICollectionView's version and will block the main thread
* while all the cells load.
*/
- (void)reloadDataImmediately;
/**
* Triggers a relayout of all nodes.
*
* @discussion This method invalidates and lays out every cell node in the collection.
*/
- (void)relayoutItems;
/**
* Blocks execution of the main thread until all section and row updates are committed. This method must be called from the main thread.
*/
- (void)waitUntilAllUpdatesAreCommitted;
/**
* Registers the given kind of supplementary node for use in creating node-backed supplementary views.
*
* @param elementKind The kind of supplementary node that will be requested through the data source.
*
* @discussion Use this method to register support for the use of supplementary nodes in place of the default
* `registerClass:forSupplementaryViewOfKind:withReuseIdentifier:` and `registerNib:forSupplementaryViewOfKind:withReuseIdentifier:`
* methods. This method will register an internal backing view that will host the contents of the supplementary nodes
* returned from the data source.
*/
- (void)registerSupplementaryNodeOfKind:(NSString *)elementKind;
/**
* Inserts one or more sections.
*
* @param sections An index set that specifies the sections to insert.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)insertSections:(NSIndexSet *)sections;
/**
* Deletes one or more sections.
*
* @param sections An index set that specifies the sections to delete.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)deleteSections:(NSIndexSet *)sections;
/**
* Reloads the specified sections.
*
* @param sections An index set that specifies the sections to reload.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)reloadSections:(NSIndexSet *)sections;
/**
* Moves a section to a new location.
*
* @param section The index of the section to move.
*
* @param newSection The index that is the destination of the move for the section.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection;
/**
* Inserts items at the locations identified by an array of index paths.
*
* @param indexPaths An array of NSIndexPath objects, each representing an item index and section index that together identify an item.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)insertItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
/**
* Deletes the items specified by an array of index paths.
*
* @param indexPaths An array of NSIndexPath objects identifying the items to delete.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)deleteItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
/**
* Reloads the specified items.
*
* @param indexPaths An array of NSIndexPath objects identifying the items to reload.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)reloadItemsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths;
/**
* Moves the item at a specified location to a destination location.
*
* @param indexPath The index path identifying the item to move.
*
* @param newIndexPath The index path that is the destination of the move for the item.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)moveItemAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath;
/**
* Similar to -visibleCells.
*
* @return an array containing the nodes being displayed on screen.
*/
- (NSArray<__kindof ASCellNode *> *)visibleNodes AS_WARN_UNUSED_RESULT;
/**
* Similar to -indexPathForCell:.
*
* @param cellNode a cellNode in the collection view
*
* @return The index path for this cell node.
*
* @discussion This index path returned by this method is in the _view's_ index space
* and should only be used with @c ASCollectionView directly. To get an index path suitable
* for use with your data source and @c ASCollectionNode, call @c indexPathForNode: on the
* collection node instead.
*/
- (nullable NSIndexPath *)indexPathForNode:(ASCellNode *)cellNode AS_WARN_UNUSED_RESULT;
@end
NS_ASSUME_NONNULL_END

View File

@@ -71,5 +71,10 @@ extern NSArray *ASIndexPathsForTwoDimensionalArray(NSArray <NSArray *>* twoDimen
*/
extern NSArray *ASIndexPathsForMultidimensionalArray(NSArray *MultidimensionalArray) AS_WARN_UNUSED_RESULT;
/**
* Attempt to get the object at the given index path. Returns @c nil if the index path is out of bounds.
*/
extern id ASGetElementInTwoDimensionalArray(NSArray *array, NSIndexPath *indexPath) AS_WARN_UNUSED_RESULT;
ASDISPLAYNODE_EXTERN_C_END

View File

@@ -223,3 +223,19 @@ NSArray *ASIndexPathsForMultidimensionalArray(NSArray *multidimensionalArray)
ASRecursivelyFindIndexPathsForMultidimensionalArray(multidimensionalArray, [[NSIndexPath alloc] init], res);
return res;
}
id ASGetElementInTwoDimensionalArray(NSArray *array, NSIndexPath *indexPath)
{
ASDisplayNodeCAssert(indexPath.length == 2, @"Expected index path of length 2. Index path: %@", indexPath);
NSInteger section = indexPath.section;
if (array.count <= section) {
return nil;
}
NSArray *innerArray = array[section];
NSInteger item = indexPath.item;
if (innerArray.count <= item) {
return nil;
}
return innerArray[item];
}

View File

@@ -0,0 +1,273 @@
//
// ASTableView+Undeprecated.h
// AsyncDisplayKit
//
// Created by Adlai Holler on 10/10/16.
// Copyright © 2016 Facebook. All rights reserved.
//
#import <AsyncDisplayKit/AsyncDisplayKit.h>
NS_ASSUME_NONNULL_BEGIN
/**
* Currently our public table API is on @c ASTableNode and the @c ASTableView
* API is deprecated, but the implementations still live in the view.
*
* This category lets us avoid deprecation warnings everywhere internally.
* In the future, the ASTableView public API will be eliminated and so will this file.
*/
@interface ASTableView (Undeprecated)
/**
* Initializer.
*
* @param frame A rectangle specifying the initial location and size of the table view in its superview€™s coordinates.
* The frame of the table view changes as table cells are added and deleted.
*
* @param style A constant that specifies the style of the table view. See UITableViewStyle for descriptions of valid constants.
*/
- (instancetype)initWithFrame:(CGRect)frame style:(UITableViewStyle)style;
/**
* Tuning parameters for a range type in full mode.
*
* @param rangeType The range type to get the tuning parameters for.
*
* @return A tuning parameter value for the given range type in full mode.
*
* @see ASLayoutRangeMode
* @see ASLayoutRangeType
*/
- (ASRangeTuningParameters)tuningParametersForRangeType:(ASLayoutRangeType)rangeType AS_WARN_UNUSED_RESULT;
/**
* Set the tuning parameters for a range type in full mode.
*
* @param tuningParameters The tuning parameters to store for a range type.
* @param rangeType The range type to set the tuning parameters for.
*
* @see ASLayoutRangeMode
* @see ASLayoutRangeType
*/
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeType:(ASLayoutRangeType)rangeType;
/**
* Tuning parameters for a range type in the specified mode.
*
* @param rangeMode The range mode to get the running parameters for.
* @param rangeType The range type to get the tuning parameters for.
*
* @return A tuning parameter value for the given range type in the given mode.
*
* @see ASLayoutRangeMode
* @see ASLayoutRangeType
*/
- (ASRangeTuningParameters)tuningParametersForRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType AS_WARN_UNUSED_RESULT;
/**
* Set the tuning parameters for a range type in the specified mode.
*
* @param tuningParameters The tuning parameters to store for a range type.
* @param rangeMode The range mode to set the running parameters for.
* @param rangeType The range type to set the tuning parameters for.
*
* @see ASLayoutRangeMode
* @see ASLayoutRangeType
*/
- (void)setTuningParameters:(ASRangeTuningParameters)tuningParameters forRangeMode:(ASLayoutRangeMode)rangeMode rangeType:(ASLayoutRangeType)rangeType;
/**
* Similar to -visibleCells.
*
* @return an array containing the cell nodes being displayed on screen.
*/
- (NSArray<ASCellNode *> *)visibleNodes AS_WARN_UNUSED_RESULT;
/**
* Similar to -indexPathForCell:.
*
* @param cellNode a cellNode part of the table view
*
* @return an indexPath for this cellNode
*/
- (nullable NSIndexPath *)indexPathForNode:(ASCellNode *)cellNode AS_WARN_UNUSED_RESULT;
/**
* The number of screens left to scroll before the delegate -tableView:beginBatchFetchingWithContext: is called.
*
* Defaults to two screenfuls.
*/
@property (nonatomic, assign) CGFloat leadingScreensForBatching;
/**
* Reload everything from scratch, destroying the working range and all cached nodes.
*
* @param completion block to run on completion of asynchronous loading or nil. If supplied, the block is run on
* the main thread.
* @warning This method is substantially more expensive than UITableView's version.
*/
-(void)reloadDataWithCompletion:(void (^ _Nullable)())completion;
/**
* Reload everything from scratch, destroying the working range and all cached nodes.
*
* @warning This method is substantially more expensive than UITableView's version.
*/
- (void)reloadData;
/**
* Reload everything from scratch entirely on the main thread, destroying the working range and all cached nodes.
*
* @warning This method is substantially more expensive than UITableView's version and will block the main thread while
* all the cells load.
*/
- (void)reloadDataImmediately;
/**
* Triggers a relayout of all nodes.
*
* @discussion This method invalidates and lays out every cell node in the table view.
*/
- (void)relayoutItems;
/**
* Begins a series of method calls that insert, delete, select, or reload rows and sections of the table view, with animation enabled and no completion block.
*
* @discussion You call this method to bracket a series of method calls that ends with endUpdates and that consists of operations
* to insert, delete, select, and reload rows and sections of the table view. When you call endUpdates, ASTableView begins animating
* the operations simultaneously. It's important to remember that the ASTableView will be processing the updates asynchronously after this call is completed.
*
* @warning This method must be called from the main thread.
*/
- (void)beginUpdates;
/**
* Concludes a series of method calls that insert, delete, select, or reload rows and sections of the table view, with animation enabled and no completion block.
*
* @discussion You call this method to bracket a series of method calls that begins with beginUpdates and that consists of operations
* to insert, delete, select, and reload rows and sections of the table view. When you call endUpdates, ASTableView begins animating
* the operations simultaneously. It's important to remember that the ASTableView will be processing the updates asynchronously after this call is completed.
*
* @warning This method is must be called from the main thread.
*/
- (void)endUpdates;
/**
* Concludes a series of method calls that insert, delete, select, or reload rows and sections of the table view.
* You call this method to bracket a series of method calls that begins with beginUpdates and that consists of operations
* to insert, delete, select, and reload rows and sections of the table view. When you call endUpdates, ASTableView begins animating
* the operations simultaneously. This method is must be called from the main thread. It's important to remember that the ASTableView will
* be processing the updates asynchronously after this call and are not guaranteed to be reflected in the ASTableView until
* the completion block is executed.
*
* @param animated NO to disable all animations.
* @param completion A completion handler block to execute when all of the operations are finished. This block takes a single
* Boolean parameter that contains the value YES if all of the related animations completed successfully or
* NO if they were interrupted. This parameter may be nil. If supplied, the block is run on the main thread.
*/
- (void)endUpdatesAnimated:(BOOL)animated completion:(void (^ _Nullable)(BOOL completed))completion;
/**
* Blocks execution of the main thread until all section and row updates are committed. This method must be called from the main thread.
*/
- (void)waitUntilAllUpdatesAreCommitted;
/**
* Inserts one or more sections, with an option to animate the insertion.
*
* @param sections An index set that specifies the sections to insert.
*
* @param animation A constant that indicates how the insertion is to be animated. See UITableViewRowAnimation.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)insertSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
/**
* Deletes one or more sections, with an option to animate the deletion.
*
* @param sections An index set that specifies the sections to delete.
*
* @param animation A constant that indicates how the deletion is to be animated. See UITableViewRowAnimation.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)deleteSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
/**
* Reloads the specified sections using a given animation effect.
*
* @param sections An index set that specifies the sections to reload.
*
* @param animation A constant that indicates how the reloading is to be animated. See UITableViewRowAnimation.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)reloadSections:(NSIndexSet *)sections withRowAnimation:(UITableViewRowAnimation)animation;
/**
* Moves a section to a new location.
*
* @param section The index of the section to move.
*
* @param newSection The index that is the destination of the move for the section.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)moveSection:(NSInteger)section toSection:(NSInteger)newSection;
/**
* Inserts rows at the locations identified by an array of index paths, with an option to animate the insertion.
*
* @param indexPaths An array of NSIndexPath objects, each representing a row index and section index that together identify a row.
*
* @param animation A constant that indicates how the insertion is to be animated. See UITableViewRowAnimation.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)insertRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
/**
* Deletes the rows specified by an array of index paths, with an option to animate the deletion.
*
* @param indexPaths An array of NSIndexPath objects identifying the rows to delete.
*
* @param animation A constant that indicates how the deletion is to be animated. See UITableViewRowAnimation.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)deleteRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
/**
* Reloads the specified rows using a given animation effect.
*
* @param indexPaths An array of NSIndexPath objects identifying the rows to reload.
*
* @param animation A constant that indicates how the reloading is to be animated. See UITableViewRowAnimation.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)reloadRowsAtIndexPaths:(NSArray<NSIndexPath *> *)indexPaths withRowAnimation:(UITableViewRowAnimation)animation;
/**
* Moves the row at a specified location to a destination location.
*
* @param indexPath The index path identifying the row to move.
*
* @param newIndexPath The index path that is the destination of the move for the row.
*
* @discussion This method must be called from the main thread. The asyncDataSource must be updated to reflect the changes
* before this method is called.
*/
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath;
@end
NS_ASSUME_NONNULL_END