Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add -[IGListAdapter sectionControllerForSection:] #477

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ This release closes the [2.2.0 milestone](https://github.com/Instagram/IGListKit

- Added `-[IGListAdapter visibleCellsForObject:]` API. [Sherlouk](https://github.com/Sherlouk) [(#442)](https://github.com/Instagram/IGListKit/pull/442)

- Added `-[IGListAdapter sectionControllerForSection:]` API. [Adlai-Holler](https://github.com/Adlai-Holler) [(#477)](https://github.com/Instagram/IGListKit/pull/477)

### 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 @@ -126,6 +126,15 @@ IGLK_SUBCLASSING_RESTRICTED
*/
- (void)reloadObjects:(NSArray *)objects;

/**
Query the section controller at a given section index. Constant time lookup.

@param section A section in the list.

@return An section controller or `nil` if the section does not exist.
*/
- (nullable IGListSectionController <IGListSectionType> *)sectionControllerForSection:(NSInteger)section;

/**
Query the section index of a list. Constant time lookup.

Expand Down
26 changes: 16 additions & 10 deletions Source/IGListAdapter.m
Original file line number Diff line number Diff line change
Expand Up @@ -339,6 +339,12 @@ - (void)reloadObjects:(NSArray *)objects {

#pragma mark - List Items & Sections

- (nullable IGListSectionController <IGListSectionType> *)sectionControllerForSection:(NSInteger)section {
IGAssertMainThread();

return [self.sectionMap sectionControllerForSection:section];
}

- (NSInteger)sectionForSectionController:(IGListSectionController <IGListSectionType> *)sectionController {
IGAssertMainThread();
IGParameterAssert(sectionController != nil);
Expand Down Expand Up @@ -381,7 +387,7 @@ - (NSArray *)objects {
}

- (id<IGListSupplementaryViewSource>)supplementaryViewSourceAtIndexPath:(NSIndexPath *)indexPath {
IGListSectionController<IGListSectionType> *sectionController = [self.sectionMap sectionControllerForSection:indexPath.section];
IGListSectionController<IGListSectionType> *sectionController = [self sectionControllerForSection:indexPath.section];
return [sectionController supplementaryViewSource];
}

Expand Down Expand Up @@ -443,7 +449,7 @@ - (NSArray *)visibleObjects {
- (CGSize)sizeForItemAtIndexPath:(NSIndexPath *)indexPath {
IGAssertMainThread();

IGListSectionController <IGListSectionType> *sectionController = [self.sectionMap sectionControllerForSection:indexPath.section];
IGListSectionController <IGListSectionType> *sectionController = [self sectionControllerForSection:indexPath.section];
return [sectionController sizeForItemAtIndex:indexPath.item];
}

Expand Down Expand Up @@ -641,7 +647,7 @@ - (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
IGListSectionController <IGListSectionType> * sectionController = [self.sectionMap sectionControllerForSection:section];
IGListSectionController <IGListSectionType> * sectionController = [self sectionControllerForSection:section];
IGAssert(sectionController != nil, @"Nil section controller for section %zi for item %@. Check your -diffIdentifier and -isEqual: implementations.",
section, [self.sectionMap objectForSection:section]);
const NSInteger numberOfItems = [sectionController numberOfItems];
Expand All @@ -650,7 +656,7 @@ - (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSe
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
IGListSectionController<IGListSectionType> *sectionController = [self.sectionMap sectionControllerForSection:indexPath.section];
IGListSectionController<IGListSectionType> *sectionController = [self sectionControllerForSection:indexPath.section];

// flag that a cell is being dequeued in case it tries to access a cell in the process
_isDequeuingCell = YES;
Expand All @@ -666,7 +672,7 @@ - (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cell
}

- (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath {
IGListSectionController<IGListSectionType> *sectionController = [self.sectionMap sectionControllerForSection:indexPath.section];
IGListSectionController<IGListSectionType> *sectionController = [self sectionControllerForSection:indexPath.section];
id <IGListSupplementaryViewSource> supplementarySource = [sectionController supplementaryViewSource];
UICollectionReusableView *view = [supplementarySource viewForSupplementaryElementOfKind:kind atIndex:indexPath.item];
IGAssert(view != nil, @"Returned a nil supplementary view at indexPath <%@> from section controller: <%@>, supplementary source: <%@>", indexPath, sectionController, supplementarySource);
Expand All @@ -683,7 +689,7 @@ - (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPa
[collectionViewDelegate collectionView:collectionView didSelectItemAtIndexPath:indexPath];
}

IGListSectionController <IGListSectionType> * sectionController = [self.sectionMap sectionControllerForSection:indexPath.section];
IGListSectionController <IGListSectionType> * sectionController = [self sectionControllerForSection:indexPath.section];
[sectionController didSelectItemAtIndex:indexPath.item];
}

Expand All @@ -698,7 +704,7 @@ - (void)collectionView:(UICollectionView *)collectionView willDisplayCell:(UICol
// if the section controller relationship was destroyed, reconnect it
// this happens with iOS 10 UICollectionView display range changes
if (sectionController == nil) {
sectionController = [self.sectionMap sectionControllerForSection:indexPath.section];
sectionController = [self sectionControllerForSection:indexPath.section];
[self mapCell:cell toSectionController:sectionController];
}

Expand Down Expand Up @@ -1054,17 +1060,17 @@ - (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollection

- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section {
IGAssert(![self.collectionViewDelegate respondsToSelector:_cmd], @"IGListAdapter is consuming method also implemented by the collectionViewDelegate: %@", NSStringFromSelector(_cmd));
return [[self.sectionMap sectionControllerForSection:section] inset];
return [[self sectionControllerForSection:section] inset];
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section {
IGAssert(![self.collectionViewDelegate respondsToSelector:_cmd], @"IGListAdapter is consuming method also implemented by the collectionViewDelegate: %@", NSStringFromSelector(_cmd));
return [[self.sectionMap sectionControllerForSection:section] minimumLineSpacing];
return [[self sectionControllerForSection:section] minimumLineSpacing];
}

- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section {
IGAssert(![self.collectionViewDelegate respondsToSelector:_cmd], @"IGListAdapter is consuming method also implemented by the collectionViewDelegate: %@", NSStringFromSelector(_cmd));
return [[self.sectionMap sectionControllerForSection:section] minimumInteritemSpacing];
return [[self sectionControllerForSection:section] minimumInteritemSpacing];
}

- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section {
Expand Down
9 changes: 9 additions & 0 deletions Tests/IGListAdapterTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,15 @@ - (void)test_whenQueryingSectionForObject_thatSectionReturned {
XCTAssertEqual([self.adapter sectionForObject:@3], NSNotFound);
}

- (void)test_whenQueryingSectionControllerForSection_thatControllerReturned {
self.dataSource.objects = @[@0, @1, @2];
[self.adapter reloadDataWithCompletion:nil];

XCTAssertEqual([self.adapter sectionControllerForSection:0], [self.adapter sectionControllerForObject:@0]);
XCTAssertEqual([self.adapter sectionControllerForSection:1], [self.adapter sectionControllerForObject:@1]);
XCTAssertEqual([self.adapter sectionControllerForSection:2], [self.adapter sectionControllerForObject:@2]);
}

- (void)test_whenReloadingData_withNoDataSource_thatCompletionCalledWithNO {
self.dataSource.objects = @[@1];
IGListAdapter *adapter = [[IGListAdapter alloc] initWithUpdater:[IGListReloadDataUpdater new]
Expand Down