Added -[IGListAdapter visibleCellsForObject:] API

Summary:
- Added `-[IGListAdapter visibleCellsForObject:]` API

1. Get all visible cells
2. Get the section for the object
3. Filter cells where indexPath.section of cell is equal to the object
4. Return

- [x] All tests pass. Demo project builds and runs.
- [x] I added test(s), an experiment, or detailed why my change isn't tested.
- [ ] 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)

-------------

Purely additive, can go in 2.2.0 release? Hold off on changelog until agreed.
Wanting to learn some more ObjC so gave this a shot, would appreciate some nit picking/feedback

Closes #437
Closes https://github.com/Instagram/IGListKit/pull/442

Differential Revision: D4450259

Pulled By: jessesquires

fbshipit-source-id: 521583c669fc1160212a7c46a50d62d951cafa2e
This commit is contained in:
Sherlock 2017-01-23 11:16:13 -08:00 committed by Facebook Github Bot
parent 6e00787eb7
commit 528bd33136
4 changed files with 72 additions and 0 deletions

View file

@ -25,6 +25,10 @@ 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).
### Enhancements
- Added `-[IGListAdapter visibleCellsForObject:]` API. [Sherlouk](https://github.com/Sherlouk) [(#442)](https://github.com/Instagram/IGListKit/pull/442)
### 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)

View file

@ -194,6 +194,15 @@ IGLK_SUBCLASSING_RESTRICTED
*/
- (NSArray *)visibleObjects;
/**
An unordered array of the currently visible cells for a given object.
@param object An object in the list
@return An array of collection view cells.
*/
- (NSArray<UICollectionViewCell *> *)visibleCellsForObject:(id)object;
/**
Scrolls to the sepcified object in the list adapter.

View file

@ -414,6 +414,25 @@
return [visibleObjects allObjects];
}
- (NSArray<UICollectionViewCell *> *)visibleCellsForObject:(id)object {
IGAssertMainThread();
IGParameterAssert(object != nil);
const NSInteger section = [self.sectionMap sectionForObject:object];
if (section == NSNotFound) {
return [NSArray new];
}
NSArray<UICollectionViewCell *> *visibleCells = [self.collectionView visibleCells];
UICollectionView *collectionView = self.collectionView;
NSPredicate *controllerPredicate = [NSPredicate predicateWithBlock:^BOOL(UICollectionViewCell* cell, NSDictionary* bindings) {
NSIndexPath *indexPath = [collectionView indexPathForCell:cell];
return indexPath.section == section;
}];
return [visibleCells filteredArrayUsingPredicate:controllerPredicate];
}
#pragma mark - Layout

View file

@ -596,6 +596,46 @@ XCTAssertEqual(CGPointEqualToPoint(point, p), YES); \
XCTAssertEqualObjects(visibleObjects, expectedObjects);
}
- (void)test_whenAdapterUpdated_thatVisibleCellsForObjectAreFound {
// each section controller returns n items sized 100x10
self.dataSource.objects = @[@2, @10, @5];
[self.adapter reloadDataWithCompletion:nil];
self.collectionView.contentOffset = CGPointMake(0, 80);
[self.collectionView layoutIfNeeded];
UICollectionView *collectionView = self.collectionView;
NSArray *visibleCellsForObject = [[self.adapter visibleCellsForObject:@10] sortedArrayUsingComparator:^NSComparisonResult(UICollectionViewCell* lhs, UICollectionViewCell* rhs) {
NSIndexPath *lhsIndexPath = [collectionView indexPathForCell:lhs];
NSIndexPath *rhsIndexPath = [collectionView indexPathForCell:rhs];
if (lhsIndexPath.section == rhsIndexPath.section) {
return lhsIndexPath.item > rhsIndexPath.item;
}
return lhsIndexPath.section > rhsIndexPath.section;
}];
XCTAssertEqual(visibleCellsForObject.count, 4);
XCTAssertEqual([self.collectionView indexPathForCell:visibleCellsForObject[0]].item, 6);
XCTAssertEqual([self.collectionView indexPathForCell:visibleCellsForObject[1]].item, 7);
XCTAssertEqual([self.collectionView indexPathForCell:visibleCellsForObject[2]].item, 8);
XCTAssertEqual([self.collectionView indexPathForCell:visibleCellsForObject[3]].item, 9);
NSArray *visibleCellsForObjectTwo = [self.adapter visibleCellsForObject:@5];
XCTAssertEqual(visibleCellsForObjectTwo.count, 5);
}
- (void)test_whenAdapterUpdated_thatVisibleCellsForNilObjectIsEmpty {
// each section controller returns n items sized 100x10
self.dataSource.objects = @[@2, @10, @5];
[self.adapter reloadDataWithCompletion:nil];
self.collectionView.contentOffset = CGPointMake(0, 80);
[self.collectionView layoutIfNeeded];
NSArray *visibleCellsForObject = [self.adapter visibleCellsForObject:@3];
XCTAssertEqual(visibleCellsForObject.count, 0);
}
- (void)test_whenScrollVerticallyToItem {
// # of items for each object == [item integerValue], so @2 has 2 items (cells)
self.dataSource.objects = @[@1, @2, @3, @4, @5, @6];