Skip to content

Commit

Permalink
Working ranges in stacked section controllers
Browse files Browse the repository at this point in the history
Summary:
Closes #354

- [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 have reviewed the [contributing guide](https://github.com/Instagram/IGListKit/blob/master/.github/CONTRIBUTING.md)
Closes #356

Differential Revision: D4365718

Pulled By: jessesquires

fbshipit-source-id: 41d7bcd823415e5795a069a4ef335e60e7da806a
  • Loading branch information
Ryan Nystrom authored and Facebook Github Bot committed Dec 23, 2016
1 parent c3c0e36 commit e9ad6b1
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 2 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ This release closes the [2.1.0 milestone](https://github.com/Instagram/IGListKit

- Disables `prefetchEnabled` by default on `IGListCollectionView`. [Sven Bacia](https://github.com/svenbacia) [(#323)](https://github.com/Instagram/IGListKit/pull/323)

- Working ranges now work with `IGListStackedSectionController`. [Ryan Nystrom](https://github.com/rnystrom) [(#356)](https://github.com/Instagram/IGListKit/pull/356)

### Fixes

- Avoid `UICollectionView` crashes when queueing a reload and insert/delete on the same item as well as reloading an item in a section that is animating. [Ryan Nystrom](https://github.com/rnystrom) [(#325)](https://github.com/Instagram/IGListKit/pull/325)
Expand Down
15 changes: 15 additions & 0 deletions Source/IGListStackedSectionController.m
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ - (instancetype)initWithSectionControllers:(NSArray <IGListSectionController<IGL

self.displayDelegate = self;
self.scrollDelegate = self;
self.workingRangeDelegate = self;

[self reloadData];
}
Expand Down Expand Up @@ -363,4 +364,18 @@ - (void)listAdapter:(IGListAdapter *)listAdapter didEndDraggingSectionController
}
}

#pragma mark - IGListWorkingRangeDelegate

- (void)listAdapter:(IGListAdapter *)listAdapter sectionControllerWillEnterWorkingRange:(IGListSectionController<IGListSectionType> *)sectionController {
for (IGListSectionController<IGListSectionType> *childSectionController in self.sectionControllers) {
[[childSectionController workingRangeDelegate] listAdapter:listAdapter sectionControllerWillEnterWorkingRange:childSectionController];
}
}

- (void)listAdapter:(IGListAdapter *)listAdapter sectionControllerDidExitWorkingRange:(IGListSectionController<IGListSectionType> *)sectionController {
for (IGListSectionController<IGListSectionType> *childSectionController in self.sectionControllers) {
[[childSectionController workingRangeDelegate] listAdapter:listAdapter sectionControllerDidExitWorkingRange:childSectionController];
}
}

@end
3 changes: 2 additions & 1 deletion Source/Internal/IGListStackedSectionControllerInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
<
IGListCollectionContext,
IGListDisplayDelegate,
IGListScrollDelegate
IGListScrollDelegate,
IGListWorkingRangeDelegate
>

@property (nonatomic, strong, readonly) NSOrderedSet<__kindof IGListSectionController<IGListSectionType> *> *sectionControllers;
Expand Down
53 changes: 52 additions & 1 deletion Tests/IGListStackSectionControllerTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ - (void)setUp {
self.collectionView.frame = kStackTestFrame;

self.dataSource = [[IGTestStackedDataSource alloc] init];
self.adapter = [[IGListAdapter alloc] initWithUpdater:[IGListAdapterUpdater new] viewController:nil workingRangeSize:0];
self.adapter = [[IGListAdapter alloc] initWithUpdater:[IGListAdapterUpdater new] viewController:nil workingRangeSize:1];
}

- (void)tearDown {
Expand Down Expand Up @@ -702,6 +702,57 @@ - (void)test_whenDeselectingChildSectionControllerIndex_thatCorrectCellDeselecte
XCTAssertFalse([[self.collectionView cellForItemAtIndexPath:path] isSelected]);
}

- (void)test_whenRemovingSection_withWorkingRange_thatChildSectionControllersReceiveEvents {
[self setupWithObjects:@[
[[IGTestObject alloc] initWithKey:@0 value:@[@1, @2, @3]],
[[IGTestObject alloc] initWithKey:@1 value:@[@1, @1]]
]];

IGListStackedSectionController *stack = [self.adapter sectionControllerForObject:self.dataSource.objects.firstObject];
IGListTestSection *section = stack.sectionControllers.firstObject;

id mockDelegate = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
[[mockDelegate expect] listAdapter:self.adapter sectionControllerDidExitWorkingRange:section];

section.workingRangeDelegate = mockDelegate;

self.dataSource.objects = @[
[[IGTestObject alloc] initWithKey:@1 value:@[@1, @1]],
];

XCTestExpectation *expectation = [self expectationWithDescription:NSStringFromSelector(_cmd)];

[self.adapter performUpdatesAnimated:YES completion:^(BOOL finished) {
[mockDelegate verify];
[expectation fulfill];
}];

[self waitForExpectationsWithTimeout:15 handler:nil];
}

- (void)test_whenScrolling_withWorkingRange_thatChildSectionControllersReceiveEvents {
[self setupWithObjects:@[
[[IGTestObject alloc] initWithKey:@0 value:@[@1, @2, @3]],
[[IGTestObject alloc] initWithKey:@1 value:@[@1, @2, @3]],
[[IGTestObject alloc] initWithKey:@2 value:@[@1, @2, @3]],
[[IGTestObject alloc] initWithKey:@3 value:@[@1, @2, @3]],
[[IGTestObject alloc] initWithKey:@4 value:@[@1, @1]]
]];

IGListStackedSectionController *stack = [self.adapter sectionControllerForObject:self.dataSource.objects.lastObject];
IGListTestSection *section = stack.sectionControllers.firstObject;

id mockDelegate = [OCMockObject mockForProtocol:@protocol(IGListWorkingRangeDelegate)];
[[mockDelegate expect] listAdapter:self.adapter sectionControllerWillEnterWorkingRange:section];

section.workingRangeDelegate = mockDelegate;

[self.collectionView scrollToItemAtIndexPath:[NSIndexPath indexPathForItem:0 inSection:4] atScrollPosition:UICollectionViewScrollPositionTop animated:NO];
[self.collectionView layoutIfNeeded];

[mockDelegate verify];
}

- (void)test_whenRemovingCellsFromChild_thatStackSendsDisplayEventsCorrectly {
IGTestObject *object = [[IGTestObject alloc] initWithKey:@0 value:@[@1, @2]];
[self setupWithObjects:@[object]];
Expand Down

0 comments on commit e9ad6b1

Please sign in to comment.