From afc8e2de841d773131b3f9b3183c916a620a360b Mon Sep 17 00:00:00 2001 From: Gulam Moledina Date: Thu, 15 Jun 2017 13:47:31 -0400 Subject: [PATCH 1/2] Fix CollectionView scroll behaviour when section is empty --- CHANGELOG.md | 1 + Source/IGListAdapter.m | 29 ++++++++++++++++++++--------- Tests/IGListAdapterTests.m | 37 +++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 9 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 616d56fe0..5081d37d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The changelog for `IGListKit`. Also see the [releases](https://github.com/instag ### Fixes - Prevent a crash when update queued immediately after item batch update. [Ryan Nystrom](https://github.com/rnystrom) (tbd) +- Fix `scrollToObject:supplementaryKinds:...` not scrolling when section is empty but does have supplymentary views ### Enhancements diff --git a/Source/IGListAdapter.m b/Source/IGListAdapter.m index 3d4a50505..d232db129 100644 --- a/Source/IGListAdapter.m +++ b/Source/IGListAdapter.m @@ -172,21 +172,33 @@ - (void)scrollToObject:(id)object } UICollectionView *collectionView = self.collectionView; - const NSInteger numberOfItems = [collectionView numberOfItemsInSection:section]; - if (numberOfItems == 0) { - return; - } - + UICollectionViewLayout *layout = self.collectionView.collectionViewLayout; + // force layout before continuing // this method is typcially called before pushing a view controller // thus, before the layout process has actually happened [collectionView layoutIfNeeded]; + NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:section]; + // collect the layout attributes for the cell and supplementary views for the first index // this will break if there are supplementary views beyond item 0 - NSIndexPath *indexPath = [NSIndexPath indexPathForItem:0 inSection:section]; - NSArray *attributes = [self layoutAttributesForIndexPath:indexPath supplementaryKinds:supplementaryKinds]; - + NSArray *attributes = nil; + + const NSInteger numberOfItems = [collectionView numberOfItemsInSection:section]; + if (numberOfItems > 0) { + attributes = [self layoutAttributesForIndexPath:indexPath supplementaryKinds:supplementaryKinds]; + } else { + NSMutableArray *supplementaryAttributes = [NSMutableArray new]; + for (NSString* supplementaryKind in supplementaryKinds) { + UICollectionViewLayoutAttributes *supplementaryAttribute = [layout layoutAttributesForSupplementaryViewOfKind:supplementaryKind atIndexPath:indexPath]; + if (supplementaryAttribute != nil) { + [supplementaryAttributes addObject: supplementaryAttribute]; + } + } + attributes = supplementaryAttributes; + } + CGFloat offsetMin = 0.0; CGFloat offsetMax = 0.0; for (UICollectionViewLayoutAttributes *attribute in attributes) { @@ -714,7 +726,6 @@ - (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL } } - #pragma mark - IGListCollectionContext - (CGSize)containerSize { diff --git a/Tests/IGListAdapterTests.m b/Tests/IGListAdapterTests.m index efbefc77d..ca3019f81 100644 --- a/Tests/IGListAdapterTests.m +++ b/Tests/IGListAdapterTests.m @@ -635,6 +635,43 @@ - (void)test_whenScrollVerticallyToItem { IGAssertEqualPoint([self.collectionView contentOffset], 0, 60); } +- (void)test_whenScrollVerticallyToItemInASectionWithNoCellsAndNoSupplymentaryView { + self.dataSource.objects = @[@1, @0, @3]; + [self.adapter reloadDataWithCompletion:nil]; + XCTAssertEqual([self.collectionView numberOfSections], 3); + [self.adapter scrollToObject:@1 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionNone animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); + [self.adapter scrollToObject:@0 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionNone animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); + [self.adapter scrollToObject:@3 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionNone animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 10); +} + +- (void)test_whenScrollVerticallyToItemInASectionWithNoCellsButAHeaderSupplymentaryView { + self.dataSource.objects = @[@1, @0, @3]; + [self.adapter reloadDataWithCompletion:nil]; + + IGTestSupplementarySource *supplementarySource = [IGTestSupplementarySource new]; + supplementarySource.collectionContext = self.adapter; + supplementarySource.supportedElementKinds = @[UICollectionElementKindSectionHeader]; + + IGListSectionController *controller = [self.adapter sectionControllerForObject:@0]; + controller.supplementaryViewSource = supplementarySource; + supplementarySource.sectionController = controller; + + [self.adapter performUpdatesAnimated:NO completion:nil]; + + XCTAssertEqual([self.collectionView numberOfSections], 3); + [self.adapter scrollToObject:@1 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionNone animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); + [self.adapter scrollToObject:@0 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionNone animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); + [self.adapter scrollToObject:@0 supplementaryKinds:@[UICollectionElementKindSectionHeader] scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionTop animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 10); + [self.adapter scrollToObject:@3 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionNone animated:NO]; + IGAssertEqualPoint([self.collectionView contentOffset], 0, 20); +} + - (void)test_whenScrollHorizontallyToItem { // # of items for each object == [item integerValue], so @2 has 2 items (cells) IGListTestAdapterHorizontalDataSource *dataSource = [[IGListTestAdapterHorizontalDataSource alloc] init]; From c71868a63f84eabdcd8b581045db38b669c323e4 Mon Sep 17 00:00:00 2001 From: Gulam Moledina Date: Tue, 18 Jul 2017 11:29:24 -0400 Subject: [PATCH 2/2] Fixed failing tests of `scrollToObject` method --- Tests/IGListAdapterTests.m | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Tests/IGListAdapterTests.m b/Tests/IGListAdapterTests.m index ca3019f81..ff4407d43 100644 --- a/Tests/IGListAdapterTests.m +++ b/Tests/IGListAdapterTests.m @@ -636,19 +636,19 @@ - (void)test_whenScrollVerticallyToItem { } - (void)test_whenScrollVerticallyToItemInASectionWithNoCellsAndNoSupplymentaryView { - self.dataSource.objects = @[@1, @0, @3]; + self.dataSource.objects = @[@1, @0, @300]; [self.adapter reloadDataWithCompletion:nil]; XCTAssertEqual([self.collectionView numberOfSections], 3); [self.adapter scrollToObject:@1 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionNone animated:NO]; IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); [self.adapter scrollToObject:@0 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionNone animated:NO]; IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); - [self.adapter scrollToObject:@3 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionNone animated:NO]; + [self.adapter scrollToObject:@300 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionNone animated:NO]; IGAssertEqualPoint([self.collectionView contentOffset], 0, 10); } - (void)test_whenScrollVerticallyToItemInASectionWithNoCellsButAHeaderSupplymentaryView { - self.dataSource.objects = @[@1, @0, @3]; + self.dataSource.objects = @[@1, @0, @300]; [self.adapter reloadDataWithCompletion:nil]; IGTestSupplementarySource *supplementarySource = [IGTestSupplementarySource new]; @@ -668,7 +668,7 @@ - (void)test_whenScrollVerticallyToItemInASectionWithNoCellsButAHeaderSupplyment IGAssertEqualPoint([self.collectionView contentOffset], 0, 0); [self.adapter scrollToObject:@0 supplementaryKinds:@[UICollectionElementKindSectionHeader] scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionTop animated:NO]; IGAssertEqualPoint([self.collectionView contentOffset], 0, 10); - [self.adapter scrollToObject:@3 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionNone animated:NO]; + [self.adapter scrollToObject:@300 supplementaryKinds:nil scrollDirection:UICollectionViewScrollDirectionVertical scrollPosition:UICollectionViewScrollPositionNone animated:NO]; IGAssertEqualPoint([self.collectionView contentOffset], 0, 20); }