diff --git a/CHANGELOG.md b/CHANGELOG.md index cf39713cb..2443f64f8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ This release closes the [2.0.0 milestone](https://github.com/Instagram/IGListKit ### Enhancements +- Added support for supplementaryViews created from nibs. [Rawlinxx](https://github.com/rawlinxx) [(#90)](https://github.com/Instagram/IGListKit/pull/90) - Added support for cells created from nibs. [Sven Bacia](https://github.com/svenbacia) [(#56)](https://github.com/Instagram/IGListKit/pull/56) - Added an additional initializer for `IGListSingleSectionController` to be able to support single sections created from nibs. An example can be found [here](Example/IGListKitExamples/ViewControllers/SingleSectionViewController.swift). - Fixed `-[IGListAdapter reloadDataWithCompletion:]` not returning early when `collectionView` or `dataSource` is nil and `completion` is nil. [Ben Asher](https://github.com/benasher44) [(#51)](https://github.com/Instagram/IGListKit/pull/51) diff --git a/Source/IGListAdapter.m b/Source/IGListAdapter.m index e35ad6b66..3d62ab831 100644 --- a/Source/IGListAdapter.m +++ b/Source/IGListAdapter.m @@ -74,6 +74,7 @@ - (void)setCollectionView:(IGListCollectionView *)collectionView { _registeredCellClasses = [NSMutableSet new]; _registeredNibNames = [NSMutableSet new]; _registeredSupplementaryViewIdentifiers = [NSMutableSet new]; + _registeredSupplementaryViewNibNames = [NSMutableSet new]; _collectionView = collectionView; _collectionView.dataSource = self; @@ -710,7 +711,7 @@ - (void)deselectItemAtIndex:(NSInteger)index } - (__kindof UICollectionViewCell *)dequeueReusableCellOfClass:(Class)cellClass - forSectionController:(IGListSectionController *)sectionController + forSectionController:(IGListSectionController *)sectionController atIndex:(NSInteger)index { IGAssertMainThread(); IGParameterAssert(sectionController != nil); @@ -732,7 +733,7 @@ - (UICollectionViewCell *)dequeueReusableCellWithNibName:(NSString *)nibName forSectionController:(IGListSectionController *)sectionController atIndex:(NSInteger)index { IGAssertMainThread(); - IGParameterAssert(nibName != nil); + IGParameterAssert([nibName length] > 0); IGParameterAssert(sectionController != nil); IGParameterAssert(index >= 0); UICollectionView *collectionView = self.collectionView; @@ -747,7 +748,7 @@ - (UICollectionViewCell *)dequeueReusableCellWithNibName:(NSString *)nibName } - (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind - forSectionController:(IGListSectionController *)sectionController + forSectionController:(IGListSectionController *)sectionController class:(Class)viewClass atIndex:(NSInteger)index { IGAssertMainThread(); @@ -766,6 +767,25 @@ - (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(N return [collectionView dequeueReusableSupplementaryViewOfKind:elementKind withReuseIdentifier:identifier forIndexPath:indexPath]; } +- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind + forSectionController:(IGListSectionController *)sectionController + nibName:(NSString *)nibName + bundle:(NSBundle *)bundle + atIndex:(NSInteger)index { + IGAssertMainThread(); + IGParameterAssert([nibName length] > 0); + IGParameterAssert([elementKind length] > 0); + UICollectionView *collectionView = self.collectionView; + IGAssert(collectionView != nil, @"Reloading adapter without a collection view."); + NSIndexPath *indexPath = [self indexPathForSectionController:sectionController index:index]; + if (![self.registeredSupplementaryViewNibNames containsObject:nibName]) { + [self.registeredSupplementaryViewNibNames addObject:nibName]; + UINib *nib = [UINib nibWithNibName:nibName bundle:bundle]; + [collectionView registerNib:nib forSupplementaryViewOfKind:elementKind withReuseIdentifier:nibName]; + } + return [collectionView dequeueReusableSupplementaryViewOfKind:elementKind withReuseIdentifier:nibName forIndexPath:indexPath]; +} + - (void)reloadInSectionController:(IGListSectionController *)sectionController atIndexes:(NSIndexSet *)indexes { IGAssertMainThread(); IGParameterAssert(indexes != nil); diff --git a/Source/IGListCollectionContext.h b/Source/IGListCollectionContext.h index aeaf8db88..1805729bd 100644 --- a/Source/IGListCollectionContext.h +++ b/Source/IGListCollectionContext.h @@ -125,6 +125,25 @@ NS_ASSUME_NONNULL_BEGIN class:(Class)viewClass atIndex:(NSInteger)index; +/** + Dequeues a supplementary view from the UICollectionView reuse pool. + + @param elementKind The kind of supplementary veiw. + @param sectionController The section controller requesting this information. + @param nibName The name of the nib file. + @param bundle The bundle in which to search for the nib file. If nil, this method looks for the nib file in the main bundle. + @param index The index of the supplementary vew. + + @return A supplementary view dequeued from the reuse pool or newly created. + + @note This method uses a string representation of the view class as the identifier. + */ +- (__kindof UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind + forSectionController:(IGListSectionController *)sectionController + nibName:(NSString *)nibName + bundle:(nullable NSBundle *)bundle + atIndex:(NSInteger)index; + /** Reloads cells in the section controller. diff --git a/Source/IGListStackedSectionController.m b/Source/IGListStackedSectionController.m index c3b3a9139..ccdccc7ad 100644 --- a/Source/IGListStackedSectionController.m +++ b/Source/IGListStackedSectionController.m @@ -199,8 +199,7 @@ - (UICollectionViewCell *)dequeueReusableCellOfClass:(Class)cellClass - (UICollectionViewCell *)dequeueReusableCellWithNibName:(NSString *)nibName bundle:(NSBundle *)bundle forSectionController:(IGListSectionController *)sectionController - atIndex:(NSInteger)index -{ + atIndex:(NSInteger)index { const NSUInteger offset = [self offsetForSectionController:sectionController]; return (UICollectionViewCell *_Nonnull)[self.collectionContext dequeueReusableCellWithNibName:nibName bundle:bundle @@ -219,6 +218,19 @@ - (UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString * atIndex:(index + offset)]; } +- (UICollectionReusableView *)dequeueReusableSupplementaryViewOfKind:(NSString *)elementKind + forSectionController:(IGListSectionController *)sectionController + nibName:(NSString *)nibName + bundle:(NSBundle *)bundle + atIndex:(NSInteger)index { + const NSUInteger offset = [self offsetForSectionController:sectionController]; + return (UICollectionViewCell *_Nonnull)[self.collectionContext dequeueReusableSupplementaryViewOfKind:elementKind + forSectionController:self + nibName:nibName + bundle:bundle + atIndex:(index + offset)]; +} + - (void)reloadInSectionController:(IGListSectionController *)sectionController atIndexes:(NSIndexSet *)indexes { NSIndexSet *itemIndexes = [self itemIndexesForSectionController:sectionController indexes:indexes]; [self.collectionContext reloadInSectionController:self atIndexes:itemIndexes]; diff --git a/Source/Internal/IGListAdapterInternal.h b/Source/Internal/IGListAdapterInternal.h index d14dca8f2..fc1def348 100644 --- a/Source/Internal/IGListAdapterInternal.h +++ b/Source/Internal/IGListAdapterInternal.h @@ -56,6 +56,7 @@ IGListCollectionContext @property (nonatomic, strong) NSMutableSet *registeredCellClasses; @property (nonatomic, strong) NSMutableSet *registeredNibNames; @property (nonatomic, strong) NSMutableSet *registeredSupplementaryViewIdentifiers; +@property (nonatomic, strong) NSMutableSet *registeredSupplementaryViewNibNames; - (NSArray *)indexPathsFromSectionController:(IGListSectionController *)sectionController indexes:(NSIndexSet *)indexes