mirror of
https://github.com/Instagram/IGListKit
synced 2026-05-06 06:58:26 +00:00
Summary: I'd like to be able to access the current collection view scrolling traits inside section controllers. These are expressed as three properties from `UIScrollView`: `isTracking`, `isDragging`, and `isDecelerating`. My approach is to add a new struct `IGListCollectionScrollingTraits` with these three values, and expose this to section controllers through `IGListCollectionContext`. Reviewed By: rnystrom Differential Revision: D7986814 fbshipit-source-id: 19e9bd3b89545b10238dd060a5af8c5a0f39eb82
299 lines
13 KiB
Objective-C
299 lines
13 KiB
Objective-C
/**
|
||
* Copyright (c) 2016-present, Facebook, Inc.
|
||
*
|
||
* This source code is licensed under the MIT license found in the
|
||
* LICENSE file in the root directory of this source tree.
|
||
*/
|
||
|
||
#import <UIKit/UIKit.h>
|
||
|
||
#import <IGListKit/IGListBatchContext.h>
|
||
#import <IGListKit/IGListCollectionScrollingTraits.h>
|
||
|
||
NS_ASSUME_NONNULL_BEGIN
|
||
|
||
@class IGListSectionController;
|
||
|
||
/**
|
||
The collection context provides limited access to the collection-related information that
|
||
section controllers need for operations like sizing, dequeuing cells, inserting, deleting, reloading, etc.
|
||
*/
|
||
NS_SWIFT_NAME(ListCollectionContext)
|
||
@protocol IGListCollectionContext <NSObject>
|
||
|
||
/**
|
||
The size of the collection view. You can use this for sizing cells.
|
||
*/
|
||
@property (nonatomic, readonly) CGSize containerSize;
|
||
|
||
/**
|
||
The content insets of the collection view. You can use this for sizing cells.
|
||
*/
|
||
@property (nonatomic, readonly) UIEdgeInsets containerInset;
|
||
|
||
/**
|
||
The adjusted content insets of the collection view. Equivalent to containerInset under iOS 11.
|
||
*/
|
||
@property (nonatomic, readonly) UIEdgeInsets adjustedContainerInset;
|
||
|
||
/**
|
||
The size of the collection view with content insets applied.
|
||
*/
|
||
@property (nonatomic, readonly) CGSize insetContainerSize;
|
||
|
||
/**
|
||
The current scrolling traits of the underlying collection view.
|
||
*/
|
||
@property (nonatomic, readonly) IGListCollectionScrollingTraits scrollingTraits;
|
||
|
||
/**
|
||
Returns size of the collection view relative to the section controller.
|
||
|
||
@param sectionController The section controller requesting this information.
|
||
|
||
@return The size of the collection view minus the given section controller's insets.
|
||
*/
|
||
- (CGSize)containerSizeForSectionController:(IGListSectionController *)sectionController;
|
||
|
||
/**
|
||
Returns the index of the specified cell in the collection relative to the section controller.
|
||
|
||
@param cell An existing cell in the collection.
|
||
@param sectionController The section controller requesting this information.
|
||
|
||
@return The index of the cell or `NSNotFound` if it does not exist in the collection.
|
||
*/
|
||
- (NSInteger)indexForCell:(UICollectionViewCell *)cell
|
||
sectionController:(IGListSectionController *)sectionController;
|
||
|
||
/**
|
||
Returns the cell in the collection at the specified index for the section controller.
|
||
|
||
@param index The index of the desired cell.
|
||
@param sectionController The section controller requesting this information.
|
||
|
||
@return The collection view cell, or `nil` if not found.
|
||
|
||
@warning This method may return `nil` if the cell is offscreen.
|
||
*/
|
||
- (nullable __kindof UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index
|
||
sectionController:(IGListSectionController *)sectionController;
|
||
|
||
/**
|
||
Returns the visible cells for the given section controller.
|
||
|
||
@param sectionController The section controller requesting this information.
|
||
|
||
@return An array of visible cells, or an empty array if none are found.
|
||
*/
|
||
- (NSArray<UICollectionViewCell *> *)visibleCellsForSectionController:(IGListSectionController *)sectionController;
|
||
|
||
/**
|
||
Returns the visible paths for the given section controller.
|
||
|
||
@param sectionController The section controller requesting this information.
|
||
|
||
@return An array of visible index paths, or an empty array if none are found.
|
||
*/
|
||
- (NSArray<NSIndexPath *> *)visibleIndexPathsForSectionController:(IGListSectionController *) sectionController;
|
||
|
||
/**
|
||
Deselects a cell in the collection.
|
||
|
||
@param index The index of the item to deselect.
|
||
@param sectionController The section controller requesting this information.
|
||
@param animated Pass `YES` to animate the change, `NO` otherwise.
|
||
*/
|
||
- (void)deselectItemAtIndex:(NSInteger)index
|
||
sectionController:(IGListSectionController *)sectionController
|
||
animated:(BOOL)animated;
|
||
|
||
/**
|
||
Selects a cell in the collection.
|
||
|
||
@param index The index of the item to select.
|
||
@param sectionController The section controller requesting this information.
|
||
@param animated Pass `YES` to animate the change, `NO` otherwise.
|
||
@param scrollPosition An option that specifies where the item should be positioned when scrolling finishes.
|
||
*/
|
||
- (void)selectItemAtIndex:(NSInteger)index
|
||
sectionController:(IGListSectionController *)sectionController
|
||
animated:(BOOL)animated
|
||
scrollPosition:(UICollectionViewScrollPosition)scrollPosition;
|
||
|
||
/**
|
||
Dequeues a cell from the collection view reuse pool.
|
||
|
||
@param cellClass The class of the cell you want to dequeue.
|
||
@param reuseIdentifier A reuse identifier for the specified cell. This parameter may be `nil`.
|
||
@param sectionController The section controller requesting this information.
|
||
@param index The index of the cell.
|
||
|
||
@return A cell dequeued from the reuse pool or a newly created one.
|
||
|
||
@note This method uses a string representation of the cell class as the identifier.
|
||
*/
|
||
- (__kindof UICollectionViewCell *)dequeueReusableCellOfClass:(Class)cellClass
|
||
withReuseIdentifier:(nullable NSString *)reuseIdentifier
|
||
forSectionController:(IGListSectionController *)sectionController
|
||
atIndex:(NSInteger)index;
|
||
|
||
/**
|
||
Dequeues a cell from the collection view reuse pool.
|
||
|
||
@param cellClass The class of the cell you want to dequeue.
|
||
@param sectionController The section controller requesting this information.
|
||
@param index The index of the cell.
|
||
|
||
@return A cell dequeued from the reuse pool or a newly created one.
|
||
|
||
@note This method uses a string representation of the cell class as the identifier.
|
||
*/
|
||
- (__kindof UICollectionViewCell *)dequeueReusableCellOfClass:(Class)cellClass
|
||
forSectionController:(IGListSectionController *)sectionController
|
||
atIndex:(NSInteger)index;
|
||
|
||
/**
|
||
Dequeues a cell from the collection view reuse pool.
|
||
|
||
@param nibName The name of the nib file.
|
||
@param bundle The bundle in which to search for the nib file. If `nil`, this method searches the main bundle.
|
||
@param sectionController The section controller requesting this information.
|
||
@param index The index of the cell.
|
||
|
||
@return A cell dequeued from the reuse pool or a newly created one.
|
||
|
||
@note This method uses a string representation of the cell class as the identifier.
|
||
*/
|
||
- (__kindof UICollectionViewCell *)dequeueReusableCellWithNibName:(NSString *)nibName
|
||
bundle:(nullable NSBundle *)bundle
|
||
forSectionController:(IGListSectionController *)sectionController
|
||
atIndex:(NSInteger)index;
|
||
|
||
/**
|
||
Dequeues a storyboard prototype cell from the collection view reuse pool.
|
||
|
||
@param identifier The identifier of the cell prototype in storyboard.
|
||
@param sectionController The section controller requesting this information.
|
||
@param index The index of the cell.
|
||
|
||
@return A cell dequeued from the reuse pool or a newly created one.
|
||
*/
|
||
- (__kindof UICollectionViewCell *)dequeueReusableCellFromStoryboardWithIdentifier:(NSString *)identifier
|
||
forSectionController:(IGListSectionController *)sectionController
|
||
atIndex:(NSInteger)index;
|
||
|
||
/**
|
||
Dequeues a supplementary view from the collection view reuse pool.
|
||
|
||
@param elementKind The kind of supplementary view.
|
||
@param sectionController The section controller requesting this information.
|
||
@param viewClass The class of the supplementary view.
|
||
@param index The index of the supplementary view.
|
||
|
||
@return A supplementary view dequeued from the reuse pool or a newly created one.
|
||
|
||
@note This method uses a string representation of the view class as the identifier.
|
||
*/
|
||
- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind
|
||
forSectionController:(IGListSectionController *)sectionController
|
||
class:(Class)viewClass
|
||
atIndex:(NSInteger)index;
|
||
|
||
/**
|
||
Dequeues a supplementary view from the collection view reuse pool.
|
||
|
||
@param elementKind The kind of supplementary view.
|
||
@param identifier The identifier of the supplementary view in storyboard.
|
||
@param sectionController The section controller requesting this information.
|
||
@param index The index of the supplementary view.
|
||
|
||
@return A supplementary view dequeued from the reuse pool or a newly created one.
|
||
*/
|
||
- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewFromStoryboardOfKind:(NSString *)elementKind
|
||
withIdentifier:(NSString *)identifier
|
||
forSectionController:(IGListSectionController *)sectionController
|
||
atIndex:(NSInteger)index;
|
||
/**
|
||
Dequeues a supplementary view from the collection view reuse pool.
|
||
|
||
@param elementKind The kind of supplementary view.
|
||
@param sectionController The section controller requesting this information.
|
||
@param nibName The name of the nib file.
|
||
@param bundle The bundle in which to search for the nib file. If `nil`, this method searches the main bundle.
|
||
@param index The index of the supplementary view.
|
||
|
||
@return A supplementary view dequeued from the reuse pool or a newly created one.
|
||
|
||
@note This method uses a string representation of the view class as the identifier.
|
||
*/
|
||
- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind
|
||
forSectionController:(IGListSectionController *)sectionController
|
||
nibName:(NSString *)nibName
|
||
bundle:(nullable NSBundle *)bundle
|
||
atIndex:(NSInteger)index;
|
||
|
||
/**
|
||
Invalidate the backing `UICollectionViewLayout` for all items in the section controller.
|
||
|
||
@param sectionController The section controller that needs invalidating.
|
||
@param completion An optional completion block to execute when the updates are finished.
|
||
|
||
@note This method can be wrapped in `UIView` animation APIs to control the duration or perform without animations. This
|
||
will end up calling `-[UICollectionView performBatchUpdates:completion:]` internally, so invalidated changes may not be
|
||
reflected in the cells immediately.
|
||
*/
|
||
- (void)invalidateLayoutForSectionController:(IGListSectionController *)sectionController
|
||
completion:(nullable void (^)(BOOL finished))completion;
|
||
|
||
/**
|
||
Batches and performs many cell-level updates in a single transaction.
|
||
|
||
@param animated A flag indicating if the transition should be animated.
|
||
@param updates A block with a context parameter to make mutations.
|
||
@param completion An optional completion block to execute when the updates are finished.
|
||
|
||
@note You should make state changes that impact the number of items in your section controller within the updates
|
||
block alongside changes on the context object.
|
||
|
||
For example, inside your section controllers, you may want to delete *and* insert into the data source that backs your
|
||
section controller. For example:
|
||
|
||
```
|
||
[self.collectionContext performBatchItemUpdates:^ (id<IGListBatchContext> batchContext>){
|
||
// perform data source changes inside the update block
|
||
[self.items addObject:newItem];
|
||
[self.items removeObjectAtIndex:0];
|
||
|
||
NSIndexSet *inserts = [NSIndexSet indexSetWithIndex:[self.items count] - 1];
|
||
[batchContext insertInSectionController:self atIndexes:inserts];
|
||
|
||
NSIndexSet *deletes = [NSIndexSet indexSetWithIndex:0];
|
||
[batchContext deleteInSectionController:self atIndexes:deletes];
|
||
} completion:nil];
|
||
```
|
||
|
||
@warning You **must** perform data modifications **inside** the update block. Updates will not be performed
|
||
synchronously, so you should make sure that your data source changes only when necessary.
|
||
*/
|
||
- (void)performBatchAnimated:(BOOL)animated
|
||
updates:(void (^)(id<IGListBatchContext> batchContext))updates
|
||
completion:(nullable void (^)(BOOL finished))completion;
|
||
|
||
|
||
/**
|
||
Scrolls to the specified section controller in the list.
|
||
|
||
@param sectionController The section controller.
|
||
@param index The index of the item in the section controller to which to scroll.
|
||
@param scrollPosition An option that specifies where the item should be positioned when scrolling finishes.
|
||
@param animated A flag indicating if the scrolling should be animated.
|
||
*/
|
||
- (void)scrollToSectionController:(IGListSectionController *)sectionController
|
||
atIndex:(NSInteger)index
|
||
scrollPosition:(UICollectionViewScrollPosition)scrollPosition
|
||
animated:(BOOL)animated;
|
||
|
||
@end
|
||
|
||
NS_ASSUME_NONNULL_END
|