From 36d1b8b21061741e262ee52e3de804dfd10d14ff Mon Sep 17 00:00:00 2001 From: Ofir Gluzman Date: Thu, 10 Jan 2019 08:19:04 -0800 Subject: [PATCH] Fix inconsistent state caused in UICollectionViewLayout+InteractiveReordering. (#1289) Summary: Issue fixed: #1288 - [x] All tests pass. Demo project builds and runs. - [x] I added tests, an experiment, or detailed why my change isn't tested. - [x] I added an entry to the `CHANGELOG.md` for any breaking changes, enhancements, or bug fixes. - [x] I have reviewed the [contributing guide](https://github.com/Instagram/IGListKit/blob/master/.github/CONTRIBUTING.md) Pull Request resolved: https://github.com/Instagram/IGListKit/pull/1289 Reviewed By: timonus Differential Revision: D13590406 Pulled By: rnystrom fbshipit-source-id: 0814b0c2383a185da747176bad57dfb15c7e883f --- CHANGELOG.md | 2 ++ ...llectionViewLayout+InteractiveReordering.m | 2 ++ Tests/IGListAdapterTests.m | 30 +++++++++++++++++++ 3 files changed, 34 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e93e71b7..4eefa824 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -76,6 +76,8 @@ The changelog for `IGListKit`. Also see the [releases](https://github.com/instag - Fixed binding section controllers failing to update their cells when the section controller's section changes. [Chrisna Aing](https://github.com/ccrazy88) [(#1144)](https://github.com/Instagram/IGListKit/pull/1144) +- Fixed a bug caused when applying interactive reordering on a single section item while dragging it through the last spot of the collection view and back to some (non-last) target position. [Ofir Gluzman](https://github.com/ofirgluzman) [#1289](https://github.com/Instagram/IGListKit/pull/1289) + 3.2.0 ----- diff --git a/Source/Internal/UICollectionViewLayout+InteractiveReordering.m b/Source/Internal/UICollectionViewLayout+InteractiveReordering.m index 5dbbb723..bfd473e2 100644 --- a/Source/Internal/UICollectionViewLayout+InteractiveReordering.m +++ b/Source/Internal/UICollectionViewLayout+InteractiveReordering.m @@ -93,6 +93,8 @@ static void * kIGListAdapterKey = &kIGListAdapterKey; IGListSectionController *sourceSectionController = [adapter sectionControllerForSection:sourceSectionIndex]; IGListSectionController *destinationSectionController = [adapter sectionControllerForSection:destinationSectionIndex]; + adapter.isLastInteractiveMoveToLastSectionIndex = NO; + // this is a reordering of sections themselves if ([sourceSectionController numberOfItems] == 1 && [destinationSectionController numberOfItems] == 1) { diff --git a/Tests/IGListAdapterTests.m b/Tests/IGListAdapterTests.m index 18a38e35..bb65d7bc 100644 --- a/Tests/IGListAdapterTests.m +++ b/Tests/IGListAdapterTests.m @@ -1699,4 +1699,34 @@ XCTAssertEqual(section1Objects[2], section1.sectionObject.objects[2]); } +- (void)test_whenSingleItemInSectionIsInteractivelyReorderedThorughLastSpot_indexesUpdateCorrectly { + IGListTestAdapterReorderingDataSource *dataSource = [IGListTestAdapterReorderingDataSource new]; + dataSource.objects = @[@0, @1, @2]; + self.adapter.dataSource = dataSource; + self.adapter.moveDelegate = dataSource; + + IGTestReorderableSection *section0 = (IGTestReorderableSection *)[self.adapter sectionControllerForSection:0]; + IGTestReorderableSection *section1 = (IGTestReorderableSection *)[self.adapter sectionControllerForSection:1]; + IGTestReorderableSection *section2 = (IGTestReorderableSection *)[self.adapter sectionControllerForSection:2]; + section0.sectionObject = [IGTestReorderableSectionObject sectionWithObjects:@[@0]]; + section0.isReorderable = YES; + section1.sectionObject = [IGTestReorderableSectionObject sectionWithObjects:@[@0]]; + section2.sectionObject = [IGTestReorderableSectionObject sectionWithObjects:@[@0]]; + + [self.adapter performUpdatesAnimated:NO completion:nil]; + + NSIndexPath *fromIndexPath = [NSIndexPath indexPathForItem:0 inSection:0]; + NSIndexPath *lastSpotIndexPath = [NSIndexPath indexPathForItem:1 inSection:2]; + NSIndexPath *toIndexPath = [NSIndexPath indexPathForItem:1 inSection:1]; + + // move the first section item to the middle while simulating dragging to the last spot and back. + NSIndexPath *interpretedPath = [self interpretedIndexPathFromIndexPath:fromIndexPath toIndexPath:lastSpotIndexPath]; + interpretedPath = [self interpretedIndexPathFromIndexPath:interpretedPath toIndexPath:toIndexPath]; + [self.adapter collectionView:self.collectionView moveItemAtIndexPath:fromIndexPath toIndexPath:interpretedPath]; + + XCTAssertEqual(section0, [self.adapter sectionControllerForSection:1]); + XCTAssertEqual(section1, [self.adapter sectionControllerForSection:0]); + XCTAssertEqual(section2, [self.adapter sectionControllerForSection:2]); +} + @end