Skip to content

Commit

Permalink
Merge branch 'master' into selectionDelegate
Browse files Browse the repository at this point in the history
  • Loading branch information
Sherlouk authored Jan 10, 2017
2 parents bd9f56a + dd3b9ed commit 086f902
Show file tree
Hide file tree
Showing 4 changed files with 114 additions and 5 deletions.
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ This release closes the [3.0.0 milestone](https://github.com/Instagram/IGListKit

This release closes the [2.2.0 milestone](https://github.com/Instagram/IGListKit/milestone/4).

> TBD
### Fixes

- Fix bug where emptyView's hidden status is not updated after the number of items is changed with `insertInSectionController:atIndexes:` or related methods. [Peter Edmonston](https://github.com/edmonston) [(#395)](https://github.com/Instagram/IGListKit/pull/395)

2.1.0
-----
Expand Down
31 changes: 27 additions & 4 deletions Source/IGListAdapter.m
Original file line number Diff line number Diff line change
Expand Up @@ -504,10 +504,13 @@ - (void)updateObjects:(NSArray *)objects dataSource:(id<IGListAdapterDataSource>
itemCount += [sectionController numberOfItems];
}

[self updateBackgroundViewWithItemCount:itemCount];
[self updateBackgroundViewShouldHide:itemCount > 0];
}

- (void)updateBackgroundViewWithItemCount:(NSUInteger)itemCount {
- (void)updateBackgroundViewShouldHide:(BOOL)shouldHide {
if (self.isInUpdateBlock) {
return; // will be called again when update block completes
}
UIView *backgroundView = [self.dataSource emptyViewForListAdapter:self];
// don't do anything if the client is using the same view
if (backgroundView != _collectionView.backgroundView) {
Expand All @@ -516,7 +519,18 @@ - (void)updateBackgroundViewWithItemCount:(NSUInteger)itemCount {
[_collectionView.backgroundView removeFromSuperview];
_collectionView.backgroundView = backgroundView;
}
_collectionView.backgroundView.hidden = itemCount > 0;
_collectionView.backgroundView.hidden = shouldHide;
}

- (BOOL)itemCountIsZero {
__block BOOL isZero = YES;
[self.sectionMap enumerateUsingBlock:^(id _Nonnull object, IGListSectionController<IGListSectionType> * _Nonnull sectionController, NSInteger section, BOOL * _Nonnull stop) {
if (sectionController.numberOfItems > 0) {
isZero = NO;
*stop = YES;
}
}];
return isZero;
}

- (IGListSectionMap *)sectionMapAdjustForUpdateBlock:(BOOL)adjustForUpdateBlock {
Expand Down Expand Up @@ -918,6 +932,7 @@ - (void)reloadInSectionController:(IGListSectionController<IGListSectionType> *)
} else {
NSArray *indexPaths = [self indexPathsFromSectionController:sectionController indexes:indexes adjustForUpdateBlock:YES];
[self.updater reloadItemsInCollectionView:collectionView indexPaths:indexPaths];
[self updateBackgroundViewShouldHide:![self itemCountIsZero]];
}
}

Expand All @@ -934,6 +949,7 @@ - (void)insertInSectionController:(IGListSectionController<IGListSectionType> *)

NSArray *indexPaths = [self indexPathsFromSectionController:sectionController indexes:indexes adjustForUpdateBlock:NO];
[self.updater insertItemsIntoCollectionView:collectionView indexPaths:indexPaths];
[self updateBackgroundViewShouldHide:![self itemCountIsZero]];
}

- (void)deleteInSectionController:(IGListSectionController<IGListSectionType> *)sectionController atIndexes:(NSIndexSet *)indexes {
Expand All @@ -949,6 +965,7 @@ - (void)deleteInSectionController:(IGListSectionController<IGListSectionType> *)

NSArray *indexPaths = [self indexPathsFromSectionController:sectionController indexes:indexes adjustForUpdateBlock:YES];
[self.updater deleteItemsFromCollectionView:collectionView indexPaths:indexPaths];
[self updateBackgroundViewShouldHide:![self itemCountIsZero]];
}

- (void)reloadSectionController:(IGListSectionController <IGListSectionType> *)sectionController {
Expand All @@ -965,6 +982,7 @@ - (void)reloadSectionController:(IGListSectionController <IGListSectionType> *)s

NSIndexSet *sections = [NSIndexSet indexSetWithIndex:section];
[self.updater reloadCollectionView:collectionView sections:sections];
[self updateBackgroundViewShouldHide:![self itemCountIsZero]];
}

- (void)performBatchAnimated:(BOOL)animated updates:(void (^)())updates completion:(void (^)(BOOL))completion {
Expand All @@ -978,7 +996,12 @@ - (void)performBatchAnimated:(BOOL)animated updates:(void (^)())updates completi
weakSelf.isInUpdateBlock = YES;
updates();
weakSelf.isInUpdateBlock = NO;
} completion:completion];
} completion: ^(BOOL finished) {
[weakSelf updateBackgroundViewShouldHide:![weakSelf itemCountIsZero]];
if (completion) {
completion(finished);
}
}];
}

- (void)scrollToSectionController:(IGListSectionController<IGListSectionType> *)sectionController
Expand Down
30 changes: 30 additions & 0 deletions Tests/IGListAdapterE2ETests.m
Original file line number Diff line number Diff line change
Expand Up @@ -1159,4 +1159,34 @@ - (void)test_whenDataSourceDeallocatedAfterUpdateQueued_thatUpdateSuccesfullyCom
[self waitForExpectationsWithTimeout:15 handler:nil];
}

- (void)test_whenQueuingUpdate_withSectionControllerBatchUpdate_thatSectionControllerNotRetained {
__weak id weakSectionController = nil;
@autoreleasepool {
IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:[IGListAdapterUpdater new] viewController:nil workingRangeSize:0];
IGTestDelegateDataSource *dataSource = [IGTestDelegateDataSource new];
IGTestObject *object = genTestObject(@1, @2);
dataSource.objects = @[object];
IGListCollectionView *collectionView = [[IGListCollectionView alloc] initWithFrame:CGRectMake(0, 0, 100, 100) collectionViewLayout:[UICollectionViewFlowLayout new]];
adapter.collectionView = collectionView;
adapter.dataSource = dataSource;
[collectionView layoutIfNeeded];
XCTAssertEqual([collectionView numberOfSections], 1);
XCTAssertEqual([collectionView numberOfItemsInSection:0], 2);

IGListSectionController<IGListSectionType> *section = [adapter sectionControllerForObject:object];

[section.collectionContext performBatchAnimated:YES updates:^{
object.value = @3;
[section.collectionContext insertInSectionController:section atIndexes:[NSIndexSet indexSetWithIndex:0]];
} completion:^(BOOL finished) {}];

dataSource.objects = @[object, genTestObject(@2, @2)];
[adapter performUpdatesAnimated:YES completion:^(BOOL finished) {}];

weakSectionController = section;
XCTAssertNotNil(weakSectionController);
}
XCTAssertNil(weakSectionController);
}

@end
54 changes: 54 additions & 0 deletions Tests/IGListAdapterTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -325,6 +325,60 @@ - (void)test_whenDataSourceAddsItems_thatEmptyViewBecomesVisible {
XCTAssertTrue(self.collectionView.backgroundView.hidden);
}

- (void)test_whenInsertingIntoEmptySection_thatEmptyViewBecomesHidden {
self.dataSource.objects = @[@0];
self.dataSource.backgroundView = [UIView new];
[self.adapter reloadDataWithCompletion:nil];
XCTAssertFalse(self.collectionView.backgroundView.hidden);
IGListTestSection *sectionController = [self.adapter sectionControllerForObject:@(0)];
sectionController.items = 1;
[self.adapter insertInSectionController:sectionController atIndexes:[NSIndexSet indexSetWithIndex:0]];
XCTAssertTrue(self.collectionView.backgroundView.hidden);
}

- (void)test_whenDeletingAllItemsFromSection_thatEmptyViewBecomesVisible {
self.dataSource.objects = @[@1];
self.dataSource.backgroundView = [UIView new];
[self.adapter reloadDataWithCompletion:nil];
XCTAssertTrue(self.collectionView.backgroundView.hidden);
IGListTestSection *sectionController = [self.adapter sectionControllerForObject:@(1)];
sectionController.items = 0;
[self.adapter deleteInSectionController:sectionController atIndexes:[NSIndexSet indexSetWithIndex:0]];
XCTAssertFalse(self.collectionView.backgroundView.hidden);
}

- (void)test_whenEmptySectionAddsItems_thatEmptyViewBecomesHidden {
self.dataSource.objects = @[@0];
self.dataSource.backgroundView = [UIView new];
[self.adapter reloadDataWithCompletion:nil];
XCTAssertFalse(self.collectionView.backgroundView.hidden);
IGListTestSection *sectionController = [self.adapter sectionControllerForObject:@(0)];
sectionController.items = 2;
[self.adapter reloadSectionController:sectionController];
XCTAssertTrue(self.collectionView.backgroundView.hidden);
}

- (void)test_whenSectionItemsAreDeletedAsBatch_thatEmptyViewBecomesVisible {
self.dataSource.objects = @[@1, @2];
self.dataSource.backgroundView = [UIView new];
[self.adapter reloadDataWithCompletion:nil];
XCTAssertTrue(self.collectionView.backgroundView.hidden);
IGListTestSection *firstSectionController = [self.adapter sectionControllerForObject:@(1)];
IGListTestSection *secondSectionController = [self.adapter sectionControllerForObject:@(2)];
XCTestExpectation *expectation = [self expectationWithDescription:NSStringFromSelector(_cmd)];
[self.adapter performBatchAnimated:YES updates:^{
firstSectionController.items = 0;
[self.adapter deleteInSectionController:firstSectionController atIndexes:[NSIndexSet indexSetWithIndex:0]];
secondSectionController.items = 0;
NSIndexSet *indexesToDelete = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, 2)];
[self.adapter deleteInSectionController:secondSectionController atIndexes:indexesToDelete];
} completion:^(BOOL finished) {
XCTAssertFalse(self.collectionView.backgroundView.hidden);
[expectation fulfill];
}];
[self waitForExpectationsWithTimeout:15 handler:nil];
}

- (void)test_whenScrollViewDelegateSet_thatDelegateReceivesEvents {
id mockDelegate = [OCMockObject mockForProtocol:@protocol(UIScrollViewDelegate)];

Expand Down

0 comments on commit 086f902

Please sign in to comment.