From 0ac855df99acbc423e56411a8d21aa73af2d9864 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dennis=20M=C3=BCller?= Date: Sun, 23 Jun 2019 23:21:53 -0700 Subject: [PATCH] Fix - Cell Reordering in IGListBindingSectionController (viewModels array not being updated) (#1274) Summary: - See #1262 (cell reordering using a binding section controller caused problems) ## Changes in this pull request - Added method override in `IGListBindingSectionController` to update the internal `viewModels` array after a cell has been moved - Subclasses of IGListBindingSectionController require to call super Issue fixed: #1262 I've added a test for this change. Is this enough? Or should I add more corner cases or something? ### Checklist Some tests fail, but they do seem unrelated. I don't know if this is normal. I haven't changed anything regarding those failing tests. - [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/1274 Reviewed By: candance Differential Revision: D15592822 Pulled By: lorixx fbshipit-source-id: d81c18bec0ad0a6a6613089245352bb182a92f26 --- CHANGELOG.md | 1 + Source/IGListBindingSectionController.h | 10 ++++++++++ Source/IGListBindingSectionController.m | 10 ++++++++++ Tests/IGListBindingSectionControllerTests.m | 16 ++++++++++++++++ 4 files changed, 37 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index d1f42e62f..4b70d7037 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,6 +45,7 @@ The changelog for `IGListKit`. Also see the [releases](https://github.com/instag - Removed `nibName` argument from `IGListReusableViewIdentifier`. [Trung Duc](https://github.com/trungducc) [(#1223)](https://github.com/Instagram/IGListKit/issues/1223) - Fixed crash when using `-[IGListCollectionContext dequeueReusableCellOfClass:withReuseIdentifier:forSectionController:atIndex:]` [Jeremy Lawrence](https://github.com/ziewvater) (tbd) +- Added missing method override to `IGListBindingSectionController` that updates the internal `viewModels` array after moving a cell. [Dennis Müller](https://github.com/d3mueller) (see [#1262](https://github.com/Instagram/IGListKit/issues/1262)) - Fixed logic flaw in `[IGListCollectionViewLayout shouldInvalidateLayoutForBoundsChange:]`. [Allen Hsu](https://github.com/allenhsu) (tbd) diff --git a/Source/IGListBindingSectionController.h b/Source/IGListBindingSectionController.h index 969f62def..17edd11b1 100644 --- a/Source/IGListBindingSectionController.h +++ b/Source/IGListBindingSectionController.h @@ -77,6 +77,16 @@ NS_SWIFT_NAME(ListBindingSectionController) */ - (void)updateAnimated:(BOOL)animated completion:(nullable void (^)(BOOL updated))completion; +/** + Notifies the section that a list object should move within a section as the result of interactive reordering. + + @param sourceIndex The starting index of the object. + @param destinationIndex The ending index of the object. + + @note this method must be implemented if interactive reordering is enabled. To ensure updating the internal viewModels array, **calling super is required**, preferably before your own implementation. + */ +- (void)moveObjectFromIndex:(NSInteger)sourceIndex toIndex:(NSInteger)destinationIndex NS_REQUIRES_SUPER; + @end NS_ASSUME_NONNULL_END diff --git a/Source/IGListBindingSectionController.m b/Source/IGListBindingSectionController.m index 50149cbb3..d18c5844f 100644 --- a/Source/IGListBindingSectionController.m +++ b/Source/IGListBindingSectionController.m @@ -127,6 +127,16 @@ - (void)didUpdateToObject:(id)object { } } +- (void)moveObjectFromIndex:(NSInteger)sourceIndex toIndex:(NSInteger)destinationIndex { + NSMutableArray *viewModels = [self.viewModels mutableCopy]; + + id modelAtSource = [viewModels objectAtIndex:sourceIndex]; + [viewModels removeObjectAtIndex:sourceIndex]; + [viewModels insertObject:modelAtSource atIndex:destinationIndex]; + + self.viewModels = viewModels; +} + - (void)didSelectItemAtIndex:(NSInteger)index { [self.selectionDelegate sectionController:self didSelectItemAtIndex:index viewModel:self.viewModels[index]]; } diff --git a/Tests/IGListBindingSectionControllerTests.m b/Tests/IGListBindingSectionControllerTests.m index a11735bc9..37c999751 100644 --- a/Tests/IGListBindingSectionControllerTests.m +++ b/Tests/IGListBindingSectionControllerTests.m @@ -465,5 +465,21 @@ - (void)test_whenUpdatingManully_withInvalidateLayoutForUpdates_thatCellSizeUpda [self waitForExpectationsWithTimeout:30 handler:nil]; } +- (void)test_viewModelsUpdate_afterCellHasBeenMoved { + [self setupWithObjects:@[ + [[IGTestDiffingObject alloc] initWithKey:@1 objects:@[@7, @"seven", @20]], + ]]; + + IGTestDiffingSectionController *section = [self.adapter sectionControllerForObject:self.dataSource.objects.firstObject]; + + [section moveObjectFromIndex:0 toIndex:2]; + XCTAssertEqual([section.viewModels firstObject], @"seven"); + XCTAssertEqual([section.viewModels lastObject], @7); + + [section moveObjectFromIndex:2 toIndex:1]; + XCTAssertEqual([section.viewModels objectAtIndex: 1], @7); + XCTAssertEqual([section.viewModels lastObject], @20); +} + @end