Skip to content

Commit

Permalink
Added -[IGListAdapter visibleCellsForObject:] API
Browse files Browse the repository at this point in the history
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 #442

Differential Revision: D4450259

Pulled By: jessesquires

fbshipit-source-id: 521583c669fc1160212a7c46a50d62d951cafa2e
  • Loading branch information
Sherlock authored and facebook-github-bot committed Jan 23, 2017
1 parent 6e00787 commit 528bd33
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
9 changes: 9 additions & 0 deletions Source/IGListAdapter.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
19 changes: 19 additions & 0 deletions Source/IGListAdapter.m
Original file line number Diff line number Diff line change
Expand Up @@ -414,6 +414,25 @@ - (NSArray *)visibleObjects {
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

Expand Down
40 changes: 40 additions & 0 deletions Tests/IGListAdapterTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -596,6 +596,46 @@ - (void)test_whenAdapterUpdated_withObjectsOverflow_thatVisibleObjectsIsSubsetOf
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];
Expand Down

0 comments on commit 528bd33

Please sign in to comment.