Add dequeue method with reuse identifier

Summary: Added the ability to register/dequeue a cell with a customized reuse identifier. This will allow for registering the same cell class for multiple reuse identifiers, as will be needed for `IGListItemView` cells.

Reviewed By: rnystrom

Differential Revision: D7436575

fbshipit-source-id: d557836b5454c50611c5a5f9367f2f2e496c3878
This commit is contained in:
Jeremy Lawrence 2018-04-02 09:03:54 -07:00 committed by Facebook Github Bot
parent df18195d18
commit f47753e361
6 changed files with 49 additions and 10 deletions

View file

@ -11,6 +11,8 @@ The changelog for `IGListKit`. Also see the [releases](https://github.com/instag
- 5x improvement to diffing performance when result is only inserts or deletes. [Ryan Nystrom](https://github.com/rnystrom) [(tbd)](tbd)
- Added `-[IGListCollectionContext dequeueReusableCellOfClass:withReuseIdentifier:forSectionController:atIndex:]` to allow for registering cells of the same class with different reuse identifiers. [Jeremy Lawrence](https://github.com/Ziewvater) (tbd)
### Fixes
- Copy objects when retrieving from datasource to prevent modification of models in binding section controller. [Kashish Goel](https://github.com/kashishgoel) [(#1109)](https://github.com/Instagram/IGListKit/pull/1109)

View file

@ -929,15 +929,16 @@
}
- (__kindof UICollectionViewCell *)dequeueReusableCellOfClass:(Class)cellClass
forSectionController:(IGListSectionController *)sectionController
atIndex:(NSInteger)index {
withReuseIdentifier:(NSString *)reuseIdentifier
forSectionController:(IGListSectionController *)sectionController
atIndex:(NSInteger)index {
IGAssertMainThread();
IGParameterAssert(sectionController != nil);
IGParameterAssert(cellClass != nil);
IGParameterAssert(index >= 0);
UICollectionView *collectionView = self.collectionView;
IGAssert(collectionView != nil, @"Dequeueing cell of class %@ from section controller %@ without a collection view at index %zi", NSStringFromClass(cellClass), sectionController, index);
NSString *identifier = IGListReusableViewIdentifier(cellClass, nil, nil);
IGAssert(collectionView != nil, @"Dequeueing cell of class %@ with reuseIdentifier %@ from section controller %@ without a collection view at index %zi", NSStringFromClass(cellClass), reuseIdentifier, sectionController, index);
NSString *identifier = IGListReusableViewIdentifier(cellClass, nil, nil, reuseIdentifier);
NSIndexPath *indexPath = [self indexPathForSectionController:sectionController index:index usePreviousIfInUpdateBlock:NO];
if (![self.registeredCellClasses containsObject:cellClass]) {
[self.registeredCellClasses addObject:cellClass];
@ -946,6 +947,12 @@
return [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];
}
- (__kindof UICollectionViewCell *)dequeueReusableCellOfClass:(Class)cellClass
forSectionController:(IGListSectionController *)sectionController
atIndex:(NSInteger)index {
return [self dequeueReusableCellOfClass:cellClass withReuseIdentifier:nil forSectionController:sectionController atIndex:index];
}
- (__kindof UICollectionViewCell *)dequeueReusableCellFromStoryboardWithIdentifier:(NSString *)identifier
forSectionController:(IGListSectionController *)sectionController
atIndex:(NSInteger)index {
@ -988,7 +995,7 @@
IGParameterAssert(index >= 0);
UICollectionView *collectionView = self.collectionView;
IGAssert(collectionView != nil, @"Dequeueing cell of class %@ from section controller %@ without a collection view at index %zi with supplementary view %@", NSStringFromClass(viewClass), sectionController, index, elementKind);
NSString *identifier = IGListReusableViewIdentifier(viewClass, nil, elementKind);
NSString *identifier = IGListReusableViewIdentifier(viewClass, nil, elementKind, nil);
NSIndexPath *indexPath = [self indexPathForSectionController:sectionController index:index usePreviousIfInUpdateBlock:NO];
if (![self.registeredSupplementaryViewIdentifiers containsObject:identifier]) {
[self.registeredSupplementaryViewIdentifiers addObject:identifier];

View file

@ -117,6 +117,23 @@ NS_SWIFT_NAME(ListCollectionContext)
animated:(BOOL)animated
scrollPosition:(UICollectionViewScrollPosition)scrollPosition;
/**
Dequeues a cell from the collection view reuse pool.
@param cellClass The class of the cell you want to dequeue.
@param reuseIdentifier A reuse identifier for the specified cell. This parameter may be `nil`.
@param sectionController The section controller requesting this information.
@param index The index of the cell.
@return A cell dequeued from the reuse pool or a newly created one.
@note This method uses a string representation of the cell class as the identifier.
*/
- (__kindof UICollectionViewCell *)dequeueReusableCellOfClass:(Class)cellClass
withReuseIdentifier:(nullable NSString *)reuseIdentifier
forSectionController:(IGListSectionController *)sectionController
atIndex:(NSInteger)index;
/**
Dequeues a cell from the collection view reuse pool.

View file

@ -296,14 +296,22 @@ static void * kStackedSectionControllerIndexKey = &kStackedSectionControllerInde
}
- (UICollectionViewCell *)dequeueReusableCellOfClass:(Class)cellClass
withReuseIdentifier:(NSString *)reuseIdentifier
forSectionController:(IGListSectionController *)sectionController
atIndex:(NSInteger)index {
const NSInteger offsetIndex = [self relativeIndexForSectionController:sectionController fromLocalIndex:index];
return (UICollectionViewCell *_Nonnull)[self.collectionContext dequeueReusableCellOfClass:cellClass
withReuseIdentifier:reuseIdentifier
forSectionController:self
atIndex:offsetIndex];
}
- (UICollectionViewCell *)dequeueReusableCellOfClass:(Class)cellClass
forSectionController:(IGListSectionController *)sectionController
atIndex:(NSInteger)index {
return [self dequeueReusableCellOfClass:cellClass withReuseIdentifier:nil forSectionController:sectionController atIndex:index];
}
- (UICollectionViewCell *)dequeueReusableCellWithNibName:(NSString *)nibName
bundle:(NSBundle *)bundle
forSectionController:(IGListSectionController *)sectionController

View file

@ -20,8 +20,8 @@
NS_ASSUME_NONNULL_BEGIN
/// Generate a string representation of a reusable view class when registering with a UICollectionView.
NS_INLINE NSString *IGListReusableViewIdentifier(Class viewClass, NSString * _Nullable nibName, NSString * _Nullable kind) {
return [NSString stringWithFormat:@"%@%@%@", kind ?: @"", nibName ?: @"", NSStringFromClass(viewClass)];
NS_INLINE NSString *IGListReusableViewIdentifier(Class viewClass, NSString * _Nullable nibName, NSString * _Nullable kind, NSString * _Nullable givenReuseIdentifier) {
return [NSString stringWithFormat:@"%@%@%@%@", kind ?: @"", nibName ?: @"", givenReuseIdentifier ?: @"", NSStringFromClass(viewClass)];
}
@interface IGListAdapter ()

View file

@ -139,18 +139,23 @@
}
- (void)test_whenQueryingReusableIdentifier_thatIdentifierEqualsClassName {
NSString *identifier = IGListReusableViewIdentifier(UICollectionViewCell.class, nil, nil);
NSString *identifier = IGListReusableViewIdentifier(UICollectionViewCell.class, nil, nil, nil);
XCTAssertEqualObjects(identifier, @"UICollectionViewCell");
}
- (void)test_whenQueryingReusableIdentifierWithGivenIdentifier_tahtIdentifierEqualsGivenIdentifierAndClassName {
NSString *identifier = IGListReusableViewIdentifier(UICollectionViewCell.class, nil, nil, @"MyCoolID");
XCTAssertEqualObjects(identifier, @"MyCoolIDUICollectionViewCell");
}
- (void)test_whenQueryingReusableIdentifier_thatIdentifierEqualsClassNameAndSupplimentaryKind {
NSString *identifier = IGListReusableViewIdentifier(UICollectionViewCell.class, nil, UICollectionElementKindSectionFooter);
NSString *identifier = IGListReusableViewIdentifier(UICollectionViewCell.class, nil, UICollectionElementKindSectionFooter, nil);
XCTAssertEqualObjects(identifier, @"UICollectionElementKindSectionFooterUICollectionViewCell");
}
- (void)test_whenQueryingReusableIdentifier_thatIdentifierEqualsClassNameAndNibName {
NSString *nibName = @"IGNibName";
NSString *identifier = IGListReusableViewIdentifier(UICollectionViewCell.class, nibName, nil);
NSString *identifier = IGListReusableViewIdentifier(UICollectionViewCell.class, nibName, nil, nil);
XCTAssertEqualObjects(identifier, @"IGNibNameUICollectionViewCell");
}