mirror of
https://github.com/Instagram/IGListKit
synced 2026-05-23 09:18:29 +00:00
Fix for #378 - emptyView not updated when items added
Summary: Modified `IGListAdapter` to update the `hidden` status of the `emptyView` after any item-level changes (`insertInSectionController:atIndexes:` and related methods) based on whether the item count is zero. Closes #378 - [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) Closes https://github.com/Instagram/IGListKit/pull/395 Differential Revision: D4400155 Pulled By: jessesquires fbshipit-source-id: 6c3422297d86947e7e2878ba1b9227ff2a2a18b4
This commit is contained in:
parent
854846921b
commit
dd3b9eddcc
3 changed files with 92 additions and 4 deletions
11
CHANGELOG.md
11
CHANGELOG.md
|
|
@ -2,6 +2,17 @@
|
|||
|
||||
The changelog for `IGListKit`. Also see the [releases](https://github.com/instagram/IGListKit/releases) on GitHub.
|
||||
|
||||
2.2.0
|
||||
-----
|
||||
|
||||
This release closes the [2.2.0 milestone](https://github.com/Instagram/IGListKit/milestone/4).
|
||||
|
||||
### Enhancements
|
||||
|
||||
### 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
|
||||
-----
|
||||
|
||||
|
|
|
|||
|
|
@ -504,10 +504,13 @@
|
|||
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) {
|
||||
|
|
@ -516,7 +519,18 @@
|
|||
[_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 {
|
||||
|
|
@ -918,6 +932,7 @@
|
|||
} else {
|
||||
NSArray *indexPaths = [self indexPathsFromSectionController:sectionController indexes:indexes adjustForUpdateBlock:YES];
|
||||
[self.updater reloadItemsInCollectionView:collectionView indexPaths:indexPaths];
|
||||
[self updateBackgroundViewShouldHide:![self itemCountIsZero]];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -934,6 +949,7 @@
|
|||
|
||||
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 {
|
||||
|
|
@ -949,6 +965,7 @@
|
|||
|
||||
NSArray *indexPaths = [self indexPathsFromSectionController:sectionController indexes:indexes adjustForUpdateBlock:YES];
|
||||
[self.updater deleteItemsFromCollectionView:collectionView indexPaths:indexPaths];
|
||||
[self updateBackgroundViewShouldHide:![self itemCountIsZero]];
|
||||
}
|
||||
|
||||
- (void)reloadSectionController:(IGListSectionController <IGListSectionType> *)sectionController {
|
||||
|
|
@ -965,6 +982,7 @@
|
|||
|
||||
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 {
|
||||
|
|
@ -978,7 +996,12 @@
|
|||
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
|
||||
|
|
|
|||
|
|
@ -325,6 +325,60 @@ XCTAssertEqual(CGPointEqualToPoint(point, p), YES); \
|
|||
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)];
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue