From e5afb5b4d0cfc70a2736b02279b6bc239ddf1e5d Mon Sep 17 00:00:00 2001 From: Jesse Squires Date: Thu, 1 Dec 2016 16:01:06 -0800 Subject: [PATCH] Add scrolling method on IGListCollectionContext. Close #267 Summary: - Add scrolling method on IGListCollectionContext so that section controllers can scroll to themselves. - Update CHANGELOG. - Other misc fixes. - Closes #267 on GitHub. Reviewed By: rnystrom Differential Revision: D4261144 fbshipit-source-id: 9eed833cfff06107607bba01a0beee1d871497b6 --- CHANGELOG.md | 22 ++++++++--- Source/IGListAdapter.h | 4 +- Source/IGListAdapter.m | 10 +++++ Source/IGListCollectionContext.h | 38 +++++++++++++------ Source/IGListStackedSectionController.m | 10 +++++ .../IGListStackedSectionControllerInternal.h | 2 +- 6 files changed, 65 insertions(+), 21 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0d064177..4224b0a4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,7 +5,7 @@ The changelog for `IGListKit`. Also see the [releases](https://github.com/instag 2.0.0 ----- -This release closes the [2.0.0 milestone](https://github.com/Instagram/IGListKit/milestone/1?closed=1). We've increased test coverage to 95%. Thanks to the [23 contributors](https://github.com/Instagram/IGListKit/graphs/contributors) who helped with this release! +This release closes the [2.0.0 milestone](https://github.com/Instagram/IGListKit/milestone/1?closed=1). We've increased test coverage to 95%. Thanks to the [24 contributors](https://github.com/Instagram/IGListKit/graphs/contributors) who helped with this release! ### Breaking Changes @@ -21,7 +21,7 @@ This release closes the [2.0.0 milestone](https://github.com/Instagram/IGListKit - `IGListDiffable` equality method changed from `isEqual:` to `isEqualToDiffableObject:` [(ab890fc)](https://github.com/Instagram/IGListKit/commit/ab890fc6070f170a2db5a383a6296e62dcf75678) -- The default `NSObject` category was removed and replaced with `NSString` and `NSNumber` categories. All other models will need to conform to `IGListDiffable`. +- The default `NSObject` category was removed and replaced with `NSString` and `NSNumber` categories. All other models will need to conform to `IGListDiffable`. - Added support for specifying an end position when scrolling. [Bofei Zhu](https://github.com/zhubofei) [(#196)](https://github.com/Instagram/IGListKit/pull/196). The `IGListAdapter` scrolling method changed: ```objc @@ -59,7 +59,7 @@ This release closes the [2.0.0 milestone](https://github.com/Instagram/IGListKit - Added `-isFirstSection` and `-isLastSection` APIs to `IGListSectionController` -- Added support for cells and supplementaryViews created from storyboard in `IGListCollectionContext`. [Bofei Zhu](https://github.com/zhubofei) [(#92)](https://github.com/Instagram/IGListKit/pull/92) +- Added support for cells and supplementaryViews created from storyboard. There's a new required method on the `IGListCollectionContext` protocol to do this. [Bofei Zhu](https://github.com/zhubofei) [(#92)](https://github.com/Instagram/IGListKit/pull/92) ```objc // IGListCollectionContext @@ -70,11 +70,21 @@ This release closes the [2.0.0 milestone](https://github.com/Instagram/IGListKit - Added `tvOS` support. [Jesse Squires](https://github.com/jessesquires) [(#137)](https://github.com/Instagram/IGListKit/pull/137) -- Added new `-[IGListAdapter visibleObjects]` API. [Ryan Nystrom](https://github.com/rnystrom) [(386ae07)](https://github.com/Instagram/IGListKit/commit/386ae0786445c06e1eabf074a4181614332f155f) +- Added `-[IGListAdapter visibleObjects]` API. [Ryan Nystrom](https://github.com/rnystrom) [(386ae07)](https://github.com/Instagram/IGListKit/commit/386ae0786445c06e1eabf074a4181614332f155f) -- Added new `-[IGListAdapter objectForSectionController:]` API. [Ayush Saraswat](https://github.com/saraswatayu) [(#204)](https://github.com/Instagram/IGListKit/pull/204) +- Added `-[IGListAdapter objectForSectionController:]` API. [Ayush Saraswat](https://github.com/saraswatayu) [(#204)](https://github.com/Instagram/IGListKit/pull/204) -- Added new `IGListGridCollectionViewLayout`, a section-based grid layout. [Bofei Zhu](https://github.com/zhubofei) [(#225)](https://github.com/Instagram/IGListKit/pull/225) +- Added `IGListGridCollectionViewLayout`, a section-based grid layout. [Bofei Zhu](https://github.com/zhubofei) [(#225)](https://github.com/Instagram/IGListKit/pull/225) + +- Added support for scrolling to an index in a section controller from within that section controller. There's a new required method on the `IGListCollectionContext` protocol to do this. [Jesse Squires](https://github.com/jessesquires) + +```objc +// IGListCollectionContext +- (void)scrollToSectionController:(IGListSectionController *)sectionController + atIndex:(NSInteger)index + scrollPosition:(UICollectionViewScrollPosition)scrollPosition + animated:(BOOL)animated; +``` ### Fixes diff --git a/Source/IGListAdapter.h b/Source/IGListAdapter.h index 914849b4..cbbac766 100644 --- a/Source/IGListAdapter.h +++ b/Source/IGListAdapter.h @@ -194,9 +194,9 @@ IGLK_SUBCLASSING_RESTRICTED @param object The object to which to scroll. @param supplementaryKinds The types of supplementary views in the section. - @param scrollDirection A flag indicating the direction to scroll. + @param scrollDirection An option indicating the direction to scroll. @param scrollPosition An option that specifies where the item should be positioned when scrolling finishes. - @param animated A flag indicating if the transition should be animated. + @param animated A flag indicating if the scrolling should be animated. */ - (void)scrollToObject:(id)object supplementaryKinds:(nullable NSArray *)supplementaryKinds diff --git a/Source/IGListAdapter.m b/Source/IGListAdapter.m index 21f0087c..168284d4 100644 --- a/Source/IGListAdapter.m +++ b/Source/IGListAdapter.m @@ -957,6 +957,16 @@ } completion:completion]; } +- (void)scrollToSectionController:(IGListSectionController *)sectionController + atIndex:(NSInteger)index + scrollPosition:(UICollectionViewScrollPosition)scrollPosition + animated:(BOOL)animated { + IGAssertMainThread(); + IGParameterAssert(sectionController != nil); + + NSIndexPath *indexPath = [self indexPathForSectionController:sectionController index:index]; + [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:scrollPosition animated:animated]; +} #pragma mark - UICollectionViewDelegateFlowLayout diff --git a/Source/IGListCollectionContext.h b/Source/IGListCollectionContext.h index 49cfdc8e..bebb501b 100644 --- a/Source/IGListCollectionContext.h +++ b/Source/IGListCollectionContext.h @@ -34,7 +34,7 @@ NS_ASSUME_NONNULL_BEGIN @return The index of the cell or `NSNotFound` if it does not exist in the collection. */ - (NSInteger)indexForCell:(UICollectionViewCell *)cell - sectionController:(IGListSectionController *)sectionController; + sectionController:(IGListSectionController *)sectionController; /** Returns the cell in the collection at the specified index for the section controller. @@ -43,7 +43,7 @@ NS_ASSUME_NONNULL_BEGIN @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 @@ -95,14 +95,14 @@ NS_ASSUME_NONNULL_BEGIN /** 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 @@ -112,11 +112,11 @@ NS_ASSUME_NONNULL_BEGIN /** 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 @@ -142,12 +142,12 @@ NS_ASSUME_NONNULL_BEGIN /** Dequeues a supplementary view from the collection view reuse pool. - + @param elementKind The kind of supplementary veiw. @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 vew. - + @return A supplementary view dequeued from the reuse pool or a newly created one. */ - (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewFromStoryboardOfKind:(NSString *)elementKind @@ -156,15 +156,15 @@ NS_ASSUME_NONNULL_BEGIN atIndex:(NSInteger)index; /** Dequeues a supplementary view from the collection view reuse pool. - + @param elementKind The kind of supplementary veiw. @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 vew. - + @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 @@ -239,6 +239,20 @@ NS_ASSUME_NONNULL_BEGIN */ - (void)performBatchAnimated:(BOOL)animated updates:(void (^)())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 diff --git a/Source/IGListStackedSectionController.m b/Source/IGListStackedSectionController.m index e1eec596..9e5f5e53 100644 --- a/Source/IGListStackedSectionController.m +++ b/Source/IGListStackedSectionController.m @@ -284,6 +284,16 @@ static void * kStackedSectionControllerIndexKey = &kStackedSectionControllerInde }]; } +- (void)scrollToSectionController:(IGListSectionController *)sectionController + atIndex:(NSInteger)index + scrollPosition:(UICollectionViewScrollPosition)scrollPosition + animated:(BOOL)animated { + const NSUInteger offset = [self offsetForSectionController:sectionController]; + [self.collectionContext scrollToSectionController:self + atIndex:(offset + index) + scrollPosition:scrollPosition + animated:animated]; +} #pragma mark - IGListDisplayDelegate diff --git a/Source/Internal/IGListStackedSectionControllerInternal.h b/Source/Internal/IGListStackedSectionControllerInternal.h index 7df67d29..2a5fb6fc 100644 --- a/Source/Internal/IGListStackedSectionControllerInternal.h +++ b/Source/Internal/IGListStackedSectionControllerInternal.h @@ -20,7 +20,7 @@ IGListScrollDelegate @property (nonatomic, strong, readonly) NSOrderedSet<__kindof IGListSectionController *> *sectionControllers; -/// An array the length of the total number of items in the stack, pointing to an section controller for the item index. +/// An array the length of the total number of items in the stack, pointing to a section controller for the item index. @property (nonatomic, copy) NSArray *> *sectionControllersForItems; /// An array of index offsets for each item in the flattened stack.