Classes
-
-
- IGListAdapter
+
+
+ IGListBatchUpdateData
Classes
IGListAdapter
objects provide an abstraction for feeds of objects in a UICollectionView
by breaking each object
-into individual sections, called section controllers
. These controllers (objects subclassing to
-IGListSectionController
) act as a data source and delegate for each section.
Feed implementations must act as the data source for an IGListAdapter
in order to drive the objects and section
-controllers in a collection view.
An instance of IGListBatchUpdateData
takes section indexes and item index paths
+and performs cleanup on init in order to perform a crash-free
+update via -[UICollectionView performBatchUpdates:completion:]
.
Declaration
Objective-C
-@interface IGListAdapter : NSObject
+@interface IGListBatchUpdateData : NSObject
Swift
-class ListAdapter : NSObject
+ class ListBatchUpdateData : NSObject
Declaration
-
-
- IGListAdapterUpdater
+
+
+ IGListIndexPathResult
Declaration
An IGListAdapterUpdater
is a concrete type that conforms to IGListUpdatingDelegate
.
-It is an out-of-box updater for IGListAdapter
objects to use.
Note
- This updater performs re-entrant, coalesced updating for a list. It also uses a least-minimal diff -for calculating UI updates whenIGListAdapter
calls
--performUpdateWithCollectionView:fromObjects:toObjects:completion:
.
-
-A result object returned when diffing with sections.
- See more + See moreDeclaration
Objective-C
-@interface IGListAdapterUpdater : NSObject <IGListUpdatingDelegate>
+@interface IGListIndexPathResult : NSObject
Swift
-class ListAdapterUpdater : NSObject, ListUpdatingDelegate
+ class ListIndexPathResult : NSObject
Declaration
-
-
- IGListBatchUpdateData
+
+
+ IGListIndexSetResult
Declaration
An instance of IGListBatchUpdateData
takes section indexes and item index paths
-and performs cleanup on init in order to perform a crash-free
-update via -[UICollectionView performBatchUpdates:completion:]
.
A result object returned when diffing with indexes.
- See more + See moreDeclaration
Objective-C
-@interface IGListBatchUpdateData : NSObject
+@interface IGListIndexSetResult : NSObject
Swift
-class ListBatchUpdateData : NSObject
+ class ListIndexSetResult : NSObject
Declaration
-
-
- IGListBindingSectionController
+
+
+ IGListMoveIndex
Declaration
This section controller uses a data source to transform its top level
object into an array of diffable view models.
-It then automatically binds each view model to cells via the IGListBindable
protocol.
Models used with IGListBindingSectionController
should take special care to always return YES
for identical
-objects. That is, any objects with matching -diffIdentifier
s should always be equal, that way the section controller
-can create new view models via the data source, create a diff, and update the specific cells that have changed.
In Objective-C, your -isEqualToDiffableObject:
can simply be:
- (BOOL)isEqualToDiffableObject:(id)object {
- return YES;
-}
-
-
-In Swift:
-func isEqual(toDiffableObject object: IGListDiffable?) -> Bool {
- return true
-}
-
-
-Only when -diffIdentifier
s match is object equality compared, so you can assume the class is the same, and the
-instance has already been checked.
An object representing a move between indexes.
- See more + See moreDeclaration
Objective-C
-@interface IGListBindingSectionController < __covariant ObjectType
- : id <IGListDiffable>
-> : IGListSectionController @end
+@interface IGListMoveIndex : NSObject
+
+ Swift
+class ListMoveIndex : NSObject
Declaration
-
-
- IGListCollectionView
+
+
+ IGListMoveIndexPath
Declaration
This UICollectionView
subclass allows for partial layout invalidation using IGListCollectionViewLayout
.
Note
- When updating a collection view (ex: calling-insertSections
), -invalidateLayoutWithContext
gets called on
-the layout object. However, the invalidation context doesn’t provide details on which index paths are being modified,
-which typically forces a full layout re-calculation. IGListCollectionView
gives IGListCollectionViewLayout
the
-missing information to re-calculate only the modified layout attributes.
-
-An object representing a move between indexes.
- See more + See moreDeclaration
Objective-C
-@interface IGListCollectionView : UICollectionView
+@interface IGListMoveIndexPath : NSObject
Swift
-class ListCollectionView : UICollectionView
+ class ListMoveIndexPath : NSObject
Declaration
-
-
- IGListCollectionViewLayout
+
+
+ IGListAdapter
Declaration
This UICollectionViewLayout subclass is for vertically or horizontally scrolling lists of data with variable widths and -heights. It supports an infinite number of sections and items. All work is done on the main thread, and while extremely efficient, -care must be taken not to stall the main thread in sizing delegate methods.
- -This layout piggybacks on the mechanics of UICollectionViewFlowLayout in that:
- --
-
- Your UICollectionView data source must also conform to UICollectionViewDelegateFlowLayout -
- Header support given via UICollectionElementKindSectionHeader -
All UICollectionViewDelegateFlowLayout methods are required and used by this layout:
-- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
-- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
-- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
-- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
-- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
-
-
-In a vertically scrolling layout, sections and items are put into the same horizontal row until the max-x position
-of an item extends beyond the width of the collection view. When that happens, the item is newlined
to the next row.
-The y position of that row is determined by the maximum height (including section insets) of the section/item of the previous row.
Ex. of a section (2,0) with a large width causing a newline.
-|[ 0,0 ][ 1,0 ] |
-|[ 2,0 ]|
-
-
-A section with a non-zero height header will always cause that section to newline. Headers are always stretched to the -width of the collection view, pinched with the section insets.
- -Ex. of a section (2,0) with a header inset on the left/right.
-|[ 0,0 ][ 1,0 ] |
-| >======header=======< |
-| [ 2,0 ] |
-
-
-Section insets apply to items in the section no matter if they begin on a new row or are on the same row as a previous -section.
- -Ex. of a section (2) with multiple items and a left inset.
-|[ 0,0 ][ 1,0 ] >[ 2,0 ]|
-| >[ 2,1 ][ 2,2 ][ 2,3 ]|
-
-
-Interitem spacing applies to items and sections within the same row. Line spacing only applies to items within the same -section.
- -In a horizontally scrolling layout, sections and items are flowed vertically until they need to be newlined
to the
-next column. Headers, if used, are stretched to the height of the collection view, minus the section insets.
IGListAdapter
objects provide an abstraction for feeds of objects in a UICollectionView
by breaking each object
+into individual sections, called section controllers
. These controllers (objects subclassing to
+IGListSectionController
) act as a data source and delegate for each section.
Please see the unit tests for more configuration examples and expected output.
+Feed implementations must act as the data source for an IGListAdapter
in order to drive the objects and section
+controllers in a collection view.
Declaration
Objective-C
-@interface IGListCollectionViewLayout : UICollectionViewLayout
+@interface IGListAdapter : NSObject
Swift
-class ListCollectionViewLayout : UICollectionViewLayout
+ class ListAdapter : NSObject
Declaration
-
-
- IGListGenericSectionController
+
+
+ IGListAdapterUpdater
Declaration
This class adds a helper layer to IGListSectionController
to automatically store a generic object in
-didUpdateToObject:
.
An IGListAdapterUpdater
is a concrete type that conforms to IGListUpdatingDelegate
.
+It is an out-of-box updater for IGListAdapter
objects to use.
Note
+ This updater performs re-entrant, coalesced updating for a list. It also uses a least-minimal diff +for calculating UI updates whenIGListAdapter
calls
+-performUpdateWithCollectionView:fromObjects:toObjects:completion:
.
- See more
+Declaration
Objective-C
-@interface IGListGenericSectionController <__covariant ObjectType> : IGListSectionController
+@interface IGListAdapterUpdater : NSObject <IGListUpdatingDelegate>
Swift
-class ListGenericSectionController<ObjectType> : ListSectionController where ObjectType : AnyObject
+ class ListAdapterUpdater : NSObject, ListUpdatingDelegate
Declaration
-
-
- IGListIndexPathResult
+
+
+ IGListBindingSectionController
Declaration
A result object returned when diffing with sections.
+This section controller uses a data source to transform its top level
object into an array of diffable view models.
+It then automatically binds each view model to cells via the IGListBindable
protocol.
Models used with IGListBindingSectionController
should take special care to always return YES
for identical
+objects. That is, any objects with matching -diffIdentifier
s should always be equal, that way the section controller
+can create new view models via the data source, create a diff, and update the specific cells that have changed.
In Objective-C, your -isEqualToDiffableObject:
can simply be:
- (BOOL)isEqualToDiffableObject:(id)object {
+ return YES;
+}
+
+
+In Swift:
+func isEqual(toDiffableObject object: IGListDiffable?) -> Bool {
+ return true
+}
+
+
+Only when -diffIdentifier
s match is object equality compared, so you can assume the class is the same, and the
+instance has already been checked.
Declaration
Objective-C
-@interface IGListIndexPathResult : NSObject
+@interface IGListBindingSectionController<
+ __covariant ObjectType : id <IGListDiffable>> : IGListSectionController
Swift
-class ListIndexPathResult : NSObject
+ class ListBindingSectionController<ObjectType> : ListSectionController where ObjectType : ListDiffable
Declaration
-
-
- IGListIndexSetResult
+
+
+ IGListCollectionView
Declaration
A result object returned when diffing with indexes.
+This UICollectionView
subclass allows for partial layout invalidation using IGListCollectionViewLayout
,
+or custom layout classes that conform to IGListCollectionViewLayoutCompatible.
Note
+ When updating a collection view (ex: calling-insertSections
), -invalidateLayoutWithContext
gets called on
+the layout object. However, the invalidation context doesn’t provide details on which index paths are being modified,
+which typically forces a full layout re-calculation. IGListCollectionView
gives IGListCollectionViewLayout
the
+missing information to re-calculate only the modified layout attributes.
- See more
+Declaration
Objective-C
-@interface IGListIndexSetResult : NSObject
+@interface IGListCollectionView : UICollectionView
Swift
-class ListIndexSetResult : NSObject
+ class ListCollectionView : UICollectionView
Declaration
-
-
- IGListMoveIndex
+
+
+ IGListCollectionViewLayout
Declaration
An object representing a move between indexes.
+This UICollectionViewLayout subclass is for vertically or horizontally scrolling lists of data with variable widths and +heights. It supports an infinite number of sections and items. All work is done on the main thread, and while extremely efficient, +care must be taken not to stall the main thread in sizing delegate methods.
- See more +This layout piggybacks on the mechanics of UICollectionViewFlowLayout in that:
+ +-
+
- Your UICollectionView data source must also conform to UICollectionViewDelegateFlowLayout +
- Header support given via UICollectionElementKindSectionHeader +
All UICollectionViewDelegateFlowLayout methods are required and used by this layout:
+- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout sizeForItemAtIndexPath:(NSIndexPath *)indexPath;
+- (UIEdgeInsets)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout insetForSectionAtIndex:(NSInteger)section;
+- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumLineSpacingForSectionAtIndex:(NSInteger)section;
+- (CGFloat)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout minimumInteritemSpacingForSectionAtIndex:(NSInteger)section;
+- (CGSize)collectionView:(UICollectionView *)collectionView layout:(UICollectionViewLayout *)collectionViewLayout referenceSizeForHeaderInSection:(NSInteger)section;
+
+
+In a vertically scrolling layout, sections and items are put into the same horizontal row until the max-x position
+of an item extends beyond the width of the collection view. When that happens, the item is newlined
to the next row.
+The y position of that row is determined by the maximum height (including section insets) of the section/item of the previous row.
Ex. of a section (2,0) with a large width causing a newline.
+|[ 0,0 ][ 1,0 ] |
+|[ 2,0 ]|
+
+
+A section with a non-zero height header will always cause that section to newline. Headers are always stretched to the +width of the collection view, pinched with the section insets.
+ +Ex. of a section (2,0) with a header inset on the left/right.
+|[ 0,0 ][ 1,0 ] |
+| >======header=======< |
+| [ 2,0 ] |
+
+
+Section insets apply to items in the section no matter if they begin on a new row or are on the same row as a previous +section.
+ +Ex. of a section (2) with multiple items and a left inset.
+|[ 0,0 ][ 1,0 ] >[ 2,0 ]|
+| >[ 2,1 ][ 2,2 ][ 2,3 ]|
+
+
+Interitem spacing applies to items and sections within the same row. Line spacing only applies to items within the same +section.
+ +In a horizontally scrolling layout, sections and items are flowed vertically until they need to be newlined
to the
+next column. Headers, if used, are stretched to the height of the collection view, minus the section insets.
Please see the unit tests for more configuration examples and expected output.
+ + See moreDeclaration
Objective-C
-@interface IGListMoveIndex : NSObject
+@interface IGListCollectionViewLayout
+ : UICollectionViewLayout <IGListCollectionViewLayoutCompatible>
Swift
-class ListMoveIndex : NSObject
+ class ListCollectionViewLayout : UICollectionViewLayout, ListCollectionViewLayoutCompatible
Declaration
-
-
- IGListMoveIndexPath
+
+
+ IGListGenericSectionController
Declaration
An object representing a move between indexes.
+This class adds a helper layer to IGListSectionController
to automatically store a generic object in
+didUpdateToObject:
.
Declaration
Objective-C
-@interface IGListMoveIndexPath : NSObject
+@interface IGListGenericSectionController<__covariant ObjectType>
+ : IGListSectionController
Swift
-class ListMoveIndexPath : NSObject
+ class ListGenericSectionController<ObjectType> : ListSectionController where ObjectType : AnyObject
Declaration
-
-
-
- --
- - - IGListStackedSectionController -
-- --- - ---An instance of
- -IGListStackedSectionController
is a clustered section controller, composed of many child section -controllers. It constructs and routes item-level indexes to the appropriate child section controller with a local -index. This lets you build section controllers made up of individual units that can be shared and reused with other -section controllers.For example, you can create a
- - See more -Comments
section controller that displays lists of text that is used alongside photo, -video, or slideshow section controllers. You then have four small and manageable section controllers instead of one -huge class.--Declaration
---Objective-C
-
- --@interface IGListStackedSectionController : IGListSectionController
--Swift
-
- -class ListStackedSectionController : ListSectionController
-
IGListAdapter
IGListAdapter
objects provide an abstraction for feeds of objects in a UICollectionView
by breaking each object
-into individual sections, called section controllers
. These controllers (objects subclassing to
+
IGListAdapter
objects provide an abstraction for feeds of objects in a UICollectionView
by breaking each object
+into individual sections, called section controllers
. These controllers (objects subclassing to
IGListSectionController
) act as a data source and delegate for each section.
Feed implementations must act as the data source for an IGListAdapter
in order to drive the objects and section
@@ -400,7 +417,7 @@
Declaration
Swift
-weak var delegate: IGListAdapterDelegate? { get set }
+ weak var delegate: ListAdapterDelegate? { get set }
Declaration
+
+
+ performanceDelegate
+
+ The object that receives IGListAdapterPerformanceDelegate
events to measure performance.
Declaration
+Objective-C
+@property (readwrite, nonatomic, nullable) id<IGListAdapterPerformanceDelegate>
+ performanceDelegate;
+
+ Swift
+weak var performanceDelegate: ListAdapterPerformanceDelegate? { get set }
+
+
@@ -607,9 +657,9 @@ Declaration
Objective-C
- (nonnull instancetype)
- initWithUpdater:(nonnull id<IGListUpdatingDelegate>)updater
- viewController:(nullable UIViewController *)viewController
-workingRangeSize:(NSInteger)workingRangeSize;
+ initWithUpdater:(nonnull id<IGListUpdatingDelegate>)updater
+ viewController:(nullable UIViewController *)viewController
+ workingRangeSize:(NSInteger)workingRangeSize;
Declaration
Objective-C
- (nonnull instancetype)
-initWithUpdater:(nonnull id<IGListUpdatingDelegate>)updater
- viewController:(nullable UIViewController *)viewController;
+ initWithUpdater:(nonnull id<IGListUpdatingDelegate>)updater
+ viewController:(nullable UIViewController *)viewController;
Declaration
Objective-C
- (void)performUpdatesAnimated:(BOOL)animated
- completion:(nullable IGListUpdaterCompletion)completion;
+ completion:(nullable IGListUpdaterCompletion)completion;
Parameters
Declaration
Objective-C
-- (void)reloadDataWithCompletion:(nullable IGListUpdaterCompletion)completion;
+ - (void)reloadDataWithCompletion:(nullable IGListUpdaterCompletion)completion;
Declaration
Swift
-func scroll(to object: Any, supplementaryKinds: [String]?, scrollDirection: UICollectionViewScrollDirection, scrollPosition: UICollectionViewScrollPosition, animated: Bool)
+ func scroll(to object: Any, supplementaryKinds: [String]?, scrollDirection: UICollectionView.ScrollDirection, scrollPosition: UICollectionView.ScrollPosition, animated: Bool)
Parameters
Declaration
Declaration
A flag indicating whether this updater should skip diffing and simply call
-reloadData
for updates when the collection view is not in a window. The default value is YES
.
A flag indicating that section reloads should be treated as item reloads, instead of converting them to delete, then insert
operations.
+This only applies if the number of items for the section is unchanged.
Note
-This will result in better performance, but will not generate the same delegate
-callbacks. If using a custom layout, it will not receive prepareForCollectionViewUpdates:
.
delete + insert, +because the collectionView can crash otherwise.
Warning
-On iOS < 8.3, this behavior is unsupported and will always be treated as NO
.
Default is NO.
Declaration
Objective-C
-@property (assign, readwrite, nonatomic) BOOL allowsBackgroundReloading;
+ @property (assign, readwrite, nonatomic) BOOL preferItemReloadsForSectionReloads;
Swift
-var allowsBackgroundReloading: Bool { get set }
+ var preferItemReloadsForSectionReloads: Bool { get set }
Declaration
-
-
- coalescanceTime
+
+
+ allowsBackgroundReloading
Declaration
Time, in seconds, to wait and coalesce batch updates. Default is 0.
+A flag indicating whether this updater should skip diffing and simply call
+reloadData
for updates when the collection view is not in a window. The default value is YES
.
Note
+This will result in better performance, but will not generate the same delegate
+callbacks. If using a custom layout, it will not receive prepareForCollectionViewUpdates:
.
Warning
+On iOS < 8.3, this behavior is unsupported and will always be treated as NO
.
Declaration
Objective-C
-@property (assign, readwrite, nonatomic) NSTimeInterval coalescanceTime;
+ @property (assign, readwrite, nonatomic) BOOL allowsBackgroundReloading;
Swift
-var coalescanceTime: TimeInterval { get set }
+ var allowsBackgroundReloading: Bool { get set }
Declaration
Declaration
+
+
+ updateIndexPaths
+
+ Item update index paths.
+ +Declaration
+Objective-C
+@property (readonly, strong, nonatomic)
+ NSArray<NSIndexPath *> *_Nonnull updateIndexPaths;
+
+ Swift
+var updateIndexPaths: [IndexPath] { get }
+
+
@@ -469,9 +519,9 @@ Declaration
-
-
- -initWithInsertSections:deleteSections:moveSections:insertIndexPaths:deleteIndexPaths:moveIndexPaths:
+
+
+ -initWithInsertSections:deleteSections:moveSections:insertIndexPaths:deleteIndexPaths:updateIndexPaths:moveIndexPaths:fixIndexPathImbalance:
@@ -487,17 +537,20 @@ Declaration
Objective-C
- (nonnull instancetype)
-initWithInsertSections:(nonnull NSIndexSet *)insertSections
- deleteSections:(nonnull NSIndexSet *)deleteSections
- moveSections:(nonnull NSSet<IGListMoveIndex *> *)moveSections
- insertIndexPaths:(nonnull NSArray<NSIndexPath *> *)insertIndexPaths
- deleteIndexPaths:(nonnull NSArray<NSIndexPath *> *)deleteIndexPaths
- moveIndexPaths:(nonnull NSArray<IGListMoveIndexPath *> *)moveIndexPaths;
+ initWithInsertSections:(nonnull NSIndexSet *)insertSections
+ deleteSections:(nonnull NSIndexSet *)deleteSections
+ moveSections:(nonnull NSSet<IGListMoveIndex *> *)moveSections
+ insertIndexPaths:(nonnull NSArray<NSIndexPath *> *)insertIndexPaths
+ deleteIndexPaths:(nonnull NSArray<NSIndexPath *> *)deleteIndexPaths
+ updateIndexPaths:(nonnull NSArray<NSIndexPath *> *)updateIndexPaths
+ moveIndexPaths:
+ (nonnull NSArray<IGListMoveIndexPath *> *)moveIndexPaths
+ fixIndexPathImbalance:(BOOL)fixIndexPathImbalance;
Swift
- init(insertSections: IndexSet, deleteSections: IndexSet, moveSections: Set<ListMoveIndex>, insert insertIndexPaths: [IndexPath], delete deleteIndexPaths: [IndexPath], moveIndexPaths: [ListMoveIndexPath])
+ init(insertSections: IndexSet, deleteSections: IndexSet, moveSections: Set<ListMoveIndex>, insert insertIndexPaths: [IndexPath], delete deleteIndexPaths: [IndexPath], update updateIndexPaths: [IndexPath], moveIndexPaths: [ListMoveIndexPath], fixIndexPathImbalance: Bool)
@@ -565,6 +618,18 @@ Parameters
+ updateIndexPaths
+
+ Item index paths to update.
+
@@ -577,6 +642,18 @@ Parameters
+ fixIndexPathImbalance
+
+ When enabled, we remove duplicate NSIndexPath inserts to avoid insert/delete imbalance and a crash.
+Return Value
+
+
+ -initWithInsertSections:deleteSections:moveSections:insertIndexPaths:deleteIndexPaths:updateIndexPaths:moveIndexPaths:
+
+ Convenience initializer with fixIndexPathImbalance disabled.
+ +Declaration
+Objective-C
+- (nonnull instancetype)
+ initWithInsertSections:(nonnull NSIndexSet *)insertSections
+ deleteSections:(nonnull NSIndexSet *)deleteSections
+ moveSections:(nonnull NSSet<IGListMoveIndex *> *)moveSections
+ insertIndexPaths:(nonnull NSArray<NSIndexPath *> *)insertIndexPaths
+ deleteIndexPaths:(nonnull NSArray<NSIndexPath *> *)deleteIndexPaths
+ updateIndexPaths:(nonnull NSArray<NSIndexPath *> *)updateIndexPaths
+ moveIndexPaths:
+ (nonnull NSArray<IGListMoveIndexPath *> *)moveIndexPaths;
+
+ Swift
+convenience init(insertSections: IndexSet, deleteSections: IndexSet, moveSections: Set<ListMoveIndex>, insert insertIndexPaths: [IndexPath], delete deleteIndexPaths: [IndexPath], update updateIndexPaths: [IndexPath], moveIndexPaths: [ListMoveIndexPath])
+
+