2016-11-23 20:42:52 +00:00
<!DOCTYPE html>
< html lang = "en" >
< head >
< title > Getting Started Reference< / title >
< link rel = "stylesheet" type = "text/css" href = "css/jazzy.css" / >
< link rel = "stylesheet" type = "text/css" href = "css/highlight.css" / >
< meta charset = 'utf-8' >
< script src = "js/jquery.min.js" defer > < / script >
< script src = "js/jazzy.js" defer > < / script >
2021-10-28 22:47:52 +00:00
< script src = "js/lunr.min.js" defer > < / script >
< script src = "js/typeahead.jquery.js" defer > < / script >
< script src = "js/jazzy.search.js" defer > < / script >
2016-11-23 20:42:52 +00:00
< / head >
< body >
< a title = "Getting Started Reference" > < / a >
< header >
< div class = "content-wrapper" >
2023-04-07 07:23:43 +00:00
< p > < a href = "index.html" > IGListKit 4.1.0 Docs< / a > (93% documented)< / p >
< p class = "header-right" > < a href = "https://github.com/Instagram/IGListKit" > < img src = "img/gh.png" alt = "GitHub" / > View on GitHub< / a > < / p >
< div class = "header-right" >
2021-10-28 22:47:52 +00:00
< form role = "search" action = "search.json" >
< input type = "text" placeholder = "Search documentation" data-typeahead >
< / form >
2023-04-07 07:23:43 +00:00
< / div >
2016-11-23 20:42:52 +00:00
< / div >
< / header >
< div class = "content-wrapper" >
< p id = "breadcrumbs" >
< a href = "index.html" > IGListKit Reference< / a >
2023-04-07 07:23:43 +00:00
< img id = "carat" src = "img/carat.png" alt = "" / >
2016-11-23 20:42:52 +00:00
Getting Started Reference
< / p >
< / div >
< div class = "content-wrapper" >
< nav class = "sidebar" >
< ul class = "nav-groups" >
< li class = "nav-group-name" >
< a href = "Guides.html" > Guides< / a >
< ul class = "nav-group-tasks" >
2017-05-12 14:19:12 +00:00
< li class = "nav-group-task" >
< a href = "best-practices-and-faq.html" > Best Practices and FAQ< / a >
< / li >
2018-04-23 16:27:43 +00:00
< li class = "nav-group-task" >
2019-11-21 00:20:23 +00:00
< a href = "generating-your-models-using-remodel.html" > Generating your models using remodel< / a >
2018-04-23 16:27:43 +00:00
< / li >
2016-11-23 20:42:52 +00:00
< li class = "nav-group-task" >
< a href = "getting-started.html" > Getting Started< / a >
< / li >
2016-11-28 00:53:20 +00:00
< li class = "nav-group-task" >
< a href = "iglistdiffable-and-equality.html" > IGListDiffable and Equality< / a >
< / li >
2016-12-27 20:37:57 +00:00
< li class = "nav-group-task" >
< a href = "installation.html" > Installation< / a >
< / li >
2016-11-23 20:42:52 +00:00
< li class = "nav-group-task" >
< a href = "migration.html" > Migration< / a >
< / li >
2017-08-23 21:12:05 +00:00
< li class = "nav-group-task" >
< a href = "modeling-and-binding.html" > Modeling and Binding< / a >
< / li >
2017-05-12 14:19:12 +00:00
< li class = "nav-group-task" >
< a href = "vision.html" > VISION< / a >
< / li >
< li class = "nav-group-task" >
< a href = "working-with-core-data.html" > Working with Core Data< / a >
< / li >
< li class = "nav-group-task" >
< a href = "working-with-uicollectionview.html" > Working with UICollectionView< / a >
< / li >
2016-11-23 20:42:52 +00:00
< / ul >
< / li >
< li class = "nav-group-name" >
< a href = "Classes.html" > Classes< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "Classes/IGListAdapter.html" > IGListAdapter< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListAdapterUpdater.html" > IGListAdapterUpdater< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListBatchUpdateData.html" > IGListBatchUpdateData< / a >
< / li >
< li class = "nav-group-task" >
2017-05-12 14:19:12 +00:00
< a href = "Classes/IGListBindingSectionController.html" > IGListBindingSectionController< / a >
< / li >
2018-02-06 23:42:25 +00:00
< li class = "nav-group-task" >
< a href = "Classes/IGListCollectionView.html" > IGListCollectionView< / a >
< / li >
2017-05-12 14:19:12 +00:00
< li class = "nav-group-task" >
< a href = "Classes/IGListCollectionViewLayout.html" > IGListCollectionViewLayout< / a >
2016-11-23 20:42:52 +00:00
< / li >
< li class = "nav-group-task" >
2017-05-12 14:19:12 +00:00
< a href = "Classes/IGListGenericSectionController.html" > IGListGenericSectionController< / a >
2016-11-23 20:42:52 +00:00
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListIndexPathResult.html" > IGListIndexPathResult< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListIndexSetResult.html" > IGListIndexSetResult< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListMoveIndex.html" > IGListMoveIndex< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListMoveIndexPath.html" > IGListMoveIndexPath< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes.html#/c:objc(cs)IGListReloadDataUpdater" > IGListReloadDataUpdater< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListSectionController.html" > IGListSectionController< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Classes/IGListSingleSectionController.html" > IGListSingleSectionController< / a >
< / li >
2023-04-07 07:23:43 +00:00
< li class = "nav-group-task" >
< a href = "Classes/IGListTransitionData.html" > IGListTransitionData< / a >
< / li >
2016-11-23 20:42:52 +00:00
< / ul >
< / li >
< li class = "nav-group-name" >
< a href = "Constants.html" > Constants< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "Constants.html#/c:@IGListKitVersionNumber" > IGListKitVersionNumber< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Constants.html#/c:@IGListKitVersionString" > IGListKitVersionString< / a >
< / li >
< / ul >
< / li >
< li class = "nav-group-name" >
2018-02-06 23:42:25 +00:00
< a href = "Enums.html" > Enumerations< / a >
2016-11-23 20:42:52 +00:00
< ul class = "nav-group-tasks" >
2018-02-06 23:42:25 +00:00
< li class = "nav-group-task" >
< a href = "Enums/IGListAdapterUpdateType.html" > IGListAdapterUpdateType< / a >
< / li >
2016-11-23 20:42:52 +00:00
< li class = "nav-group-task" >
< a href = "Enums/IGListDiffOption.html" > IGListDiffOption< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Enums/IGListExperiment.html" > IGListExperiment< / a >
< / li >
< / ul >
< / li >
< li class = "nav-group-name" >
< a href = "Protocols.html" > Protocols< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "Protocols/IGListAdapterDataSource.html" > IGListAdapterDataSource< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListAdapterDelegate.html" > IGListAdapterDelegate< / a >
< / li >
2018-04-23 16:27:43 +00:00
< li class = "nav-group-task" >
< a href = "Protocols/IGListAdapterMoveDelegate.html" > IGListAdapterMoveDelegate< / a >
< / li >
2019-11-21 00:20:23 +00:00
< li class = "nav-group-task" >
< a href = "Protocols/IGListAdapterPerformanceDelegate.html" > IGListAdapterPerformanceDelegate< / a >
< / li >
2018-02-06 23:42:25 +00:00
< li class = "nav-group-task" >
< a href = "Protocols/IGListAdapterUpdateListener.html" > IGListAdapterUpdateListener< / a >
< / li >
2016-11-23 20:42:52 +00:00
< li class = "nav-group-task" >
< a href = "Protocols/IGListAdapterUpdaterDelegate.html" > IGListAdapterUpdaterDelegate< / a >
< / li >
2017-05-12 14:19:12 +00:00
< li class = "nav-group-task" >
< a href = "Protocols/IGListBatchContext.html" > IGListBatchContext< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListBindable.html" > IGListBindable< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListBindingSectionControllerDataSource.html" > IGListBindingSectionControllerDataSource< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListBindingSectionControllerSelectionDelegate.html" > IGListBindingSectionControllerSelectionDelegate< / a >
< / li >
2016-11-23 20:42:52 +00:00
< li class = "nav-group-task" >
< a href = "Protocols/IGListCollectionContext.html" > IGListCollectionContext< / a >
< / li >
2018-02-06 23:42:25 +00:00
< li class = "nav-group-task" >
< a href = "Protocols/IGListCollectionViewDelegateLayout.html" > IGListCollectionViewDelegateLayout< / a >
< / li >
2019-11-21 00:20:23 +00:00
< li class = "nav-group-task" >
< a href = "Protocols/IGListCollectionViewLayoutCompatible.html" > IGListCollectionViewLayoutCompatible< / a >
< / li >
2016-11-23 20:42:52 +00:00
< li class = "nav-group-task" >
< a href = "Protocols/IGListDiffable.html" > IGListDiffable< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListDisplayDelegate.html" > IGListDisplayDelegate< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListScrollDelegate.html" > IGListScrollDelegate< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListSingleSectionControllerDelegate.html" > IGListSingleSectionControllerDelegate< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListSupplementaryViewSource.html" > IGListSupplementaryViewSource< / a >
< / li >
2018-02-06 23:42:25 +00:00
< li class = "nav-group-task" >
< a href = "Protocols/IGListTransitionDelegate.html" > IGListTransitionDelegate< / a >
< / li >
2016-11-23 20:42:52 +00:00
< li class = "nav-group-task" >
< a href = "Protocols/IGListUpdatingDelegate.html" > IGListUpdatingDelegate< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Protocols/IGListWorkingRangeDelegate.html" > IGListWorkingRangeDelegate< / a >
< / li >
< / ul >
< / li >
< li class = "nav-group-name" >
2019-11-21 00:20:23 +00:00
< a href = "Type%20Definitions.html" > Type Definitions< / a >
2016-11-23 20:42:52 +00:00
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
2019-11-21 00:20:23 +00:00
< a href = "Type%20Definitions/IGListCollectionScrollingTraits.html" > IGListCollectionScrollingTraits< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Type%20Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListCollectionViewBlock" > IGListCollectionViewBlock< / a >
2016-11-23 20:42:52 +00:00
< / li >
2021-10-28 22:47:52 +00:00
< li class = "nav-group-task" >
< a href = "Type%20Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListDataSourceChangeBlock" > IGListDataSourceChangeBlock< / a >
< / li >
2016-11-23 20:42:52 +00:00
< li class = "nav-group-task" >
2019-11-21 00:20:23 +00:00
< a href = "Type%20Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListItemUpdateBlock" > IGListItemUpdateBlock< / a >
2016-11-23 20:42:52 +00:00
< / li >
< li class = "nav-group-task" >
2019-11-21 00:20:23 +00:00
< a href = "Type%20Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListObjectTransitionBlock" > IGListObjectTransitionBlock< / a >
2016-11-23 20:42:52 +00:00
< / li >
< li class = "nav-group-task" >
2019-11-21 00:20:23 +00:00
< a href = "Type%20Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListReloadUpdateBlock" > IGListReloadUpdateBlock< / a >
2016-11-23 20:42:52 +00:00
< / li >
< li class = "nav-group-task" >
2019-11-21 00:20:23 +00:00
< a href = "Type%20Definitions.html#/c:IGListSingleSectionController.h@T@IGListSingleSectionCellConfigureBlock" > IGListSingleSectionCellConfigureBlock< / a >
2016-11-23 20:42:52 +00:00
< / li >
2018-05-01 23:54:35 +00:00
< li class = "nav-group-task" >
2019-11-21 00:20:23 +00:00
< a href = "Type%20Definitions.html#/c:IGListSingleSectionController.h@T@IGListSingleSectionCellSizeBlock" > IGListSingleSectionCellSizeBlock< / a >
2018-05-01 23:54:35 +00:00
< / li >
2016-11-23 20:42:52 +00:00
< li class = "nav-group-task" >
2019-11-21 00:20:23 +00:00
< a href = "Type%20Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListToObjectBlock" > IGListToObjectBlock< / a >
2016-11-23 20:42:52 +00:00
< / li >
2021-10-28 22:47:52 +00:00
< li class = "nav-group-task" >
< a href = "Type%20Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListTransitionDataApplyBlock" > IGListTransitionDataApplyBlock< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Type%20Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListTransitionDataBlock" > IGListTransitionDataBlock< / a >
< / li >
2016-11-23 20:42:52 +00:00
< li class = "nav-group-task" >
2019-11-21 00:20:23 +00:00
< a href = "Type%20Definitions.html#/c:IGListAdapter.h@T@IGListUpdaterCompletion" > IGListUpdaterCompletion< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Type%20Definitions.html#/c:IGListUpdatingDelegate.h@T@IGListUpdatingCompletion" > IGListUpdatingCompletion< / a >
2016-11-23 20:42:52 +00:00
< / li >
< / ul >
< / li >
< li class = "nav-group-name" >
< a href = "Functions.html" > Functions< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "Functions.html#/c:@F@IGListDiff" > IGListDiff< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Functions.html#/c:@F@IGListDiffPaths" > IGListDiffPaths< / a >
< / li >
< li class = "nav-group-task" >
< a href = "Functions.html#/c:IGListExperiments.h@F@IGListExperimentEnabled" > IGListExperimentEnabled< / a >
< / li >
< / ul >
< / li >
2019-11-21 00:20:23 +00:00
< li class = "nav-group-name" >
< a href = "Structs.html" > Structures< / a >
< ul class = "nav-group-tasks" >
< li class = "nav-group-task" >
< a href = "Structs/IGListCollectionScrollingTraits.html" > IGListCollectionScrollingTraits< / a >
< / li >
< / ul >
< / li >
2016-11-23 20:42:52 +00:00
< / ul >
< / nav >
< article class = "main-content" >
< section >
< section class = "section" >
2017-05-12 14:19:12 +00:00
< h1 id = 'getting-started' class = 'heading' > Getting Started< / h1 >
2016-11-23 20:42:52 +00:00
< p > This guide provides a brief overview for how to get started using < code > IGListKit< / code > .< / p >
2017-05-12 14:19:12 +00:00
< h2 id = 'creating-your-first-list' class = 'heading' > Creating your first list< / h2 >
2016-11-23 20:42:52 +00:00
< p > After installing < code > IGListKit< / code > , creating a new list is easy.< / p >
2017-05-12 14:19:12 +00:00
< h3 id = 'creating-a-section-controller' class = 'heading' > Creating a section controller< / h3 >
2016-11-23 20:42:52 +00:00
2018-02-06 23:42:25 +00:00
< p > Creating a new section controller is simple. Subclass < code > < a href = "Classes/IGListSectionController.html" > IGListSectionController< / a > < / code > and override at least < code > cellForItemAtIndex:< / code > and < code > sizeForItemAtIndex:< / code > .< / p >
2016-11-23 20:42:52 +00:00
2023-02-09 02:34:25 +00:00
< p > Take a look at < a href = "https://raw.githubusercontent.com/Instagram/IGListKit/main/Examples/Examples-iOS/IGListKitExamples/SectionControllers/LabelSectionController.swift" > LabelSectionController< / a > for an example section controller that handles a < code > String< / code > and configures a single cell with a < code > UILabel< / code > .< / p >
2017-05-12 14:19:12 +00:00
< pre class = "highlight swift" > < code > < span class = "kd" > class< / span > < span class = "kt" > LabelSectionController< / span > < span class = "p" > :< / span > < span class = "kt" > ListSectionController< / span > < span class = "p" > {< / span >
< span class = "k" > override< / span > < span class = "kd" > func< / span > < span class = "nf" > sizeForItem< / span > < span class = "p" > (< / span > < span class = "n" > at< / span > < span class = "nv" > index< / span > < span class = "p" > :< / span > < span class = "kt" > Int< / span > < span class = "p" > )< / span > < span class = "o" > -> < / span > < span class = "kt" > CGSize< / span > < span class = "p" > {< / span >
< span class = "k" > return< / span > < span class = "kt" > CGSize< / span > < span class = "p" > (< / span > < span class = "nv" > width< / span > < span class = "p" > :< / span > < span class = "n" > collectionContext< / span > < span class = "o" > !.< / span > < span class = "n" > containerSize< / span > < span class = "o" > .< / span > < span class = "n" > width< / span > < span class = "p" > ,< / span > < span class = "nv" > height< / span > < span class = "p" > :< / span > < span class = "mi" > 55< / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
< span class = "k" > override< / span > < span class = "kd" > func< / span > < span class = "nf" > cellForItem< / span > < span class = "p" > (< / span > < span class = "n" > at< / span > < span class = "nv" > index< / span > < span class = "p" > :< / span > < span class = "kt" > Int< / span > < span class = "p" > )< / span > < span class = "o" > -> < / span > < span class = "kt" > UICollectionViewCell< / span > < span class = "p" > {< / span >
< span class = "k" > return< / span > < span class = "n" > collectionContext< / span > < span class = "o" > !.< / span > < span class = "nf" > dequeueReusableCell< / span > < span class = "p" > (< / span > < span class = "nv" > of< / span > < span class = "p" > :< / span > < span class = "kt" > MyCell< / span > < span class = "o" > .< / span > < span class = "k" > self< / span > < span class = "p" > ,< / span > < span class = "nv" > for< / span > < span class = "p" > :< / span > < span class = "k" > self< / span > < span class = "p" > ,< / span > < span class = "nv" > at< / span > < span class = "p" > :< / span > < span class = "n" > index< / span > < span class = "p" > )< / span >
< span class = "p" > }< / span >
2016-11-23 20:42:52 +00:00
< span class = "p" > }< / span >
< / code > < / pre >
2017-05-12 14:19:12 +00:00
< h3 id = 'creating-the-ui' class = 'heading' > Creating the UI< / h3 >
2016-11-23 20:42:52 +00:00
2018-02-06 23:42:25 +00:00
< p > After creating at least one section controller, you must create a < code > UICollectionView< / code > and < code > < a href = "Classes/IGListAdapter.html" > IGListAdapter< / a > < / code > .< / p >
2016-11-23 20:42:52 +00:00
< pre class = "highlight swift" > < code > < span class = "k" > let< / span > < span class = "nv" > layout< / span > < span class = "o" > =< / span > < span class = "kt" > UICollectionViewFlowLayout< / span > < span class = "p" > ()< / span >
2017-05-12 14:19:12 +00:00
< span class = "k" > let< / span > < span class = "nv" > collectionView< / span > < span class = "o" > =< / span > < span class = "kt" > UICollectionView< / span > < span class = "p" > (< / span > < span class = "nv" > frame< / span > < span class = "p" > :< / span > < span class = "o" > .< / span > < span class = "n" > zero< / span > < span class = "p" > ,< / span > < span class = "nv" > collectionViewLayout< / span > < span class = "p" > :< / span > < span class = "n" > layout< / span > < span class = "p" > )< / span >
2016-11-23 20:42:52 +00:00
2017-05-12 14:19:12 +00:00
< span class = "k" > let< / span > < span class = "nv" > updater< / span > < span class = "o" > =< / span > < span class = "kt" > ListAdapterUpdater< / span > < span class = "p" > ()< / span >
2017-06-01 03:51:02 +00:00
< span class = "k" > let< / span > < span class = "nv" > adapter< / span > < span class = "o" > =< / span > < span class = "kt" > ListAdapter< / span > < span class = "p" > (< / span > < span class = "nv" > updater< / span > < span class = "p" > :< / span > < span class = "n" > updater< / span > < span class = "p" > ,< / span > < span class = "nv" > viewController< / span > < span class = "p" > :< / span > < span class = "k" > self< / span > < span class = "p" > )< / span >
2016-11-23 20:42:52 +00:00
< span class = "n" > adapter< / span > < span class = "o" > .< / span > < span class = "n" > collectionView< / span > < span class = "o" > =< / span > < span class = "n" > collectionView< / span >
< / code > < / pre >
< blockquote >
2018-02-06 23:42:25 +00:00
< p > < strong > Note:< / strong > This example is done within a < code > UIViewController< / code > and uses both a stock < code > UICollectionViewFlowLayout< / code > and < code > < a href = "Classes/IGListAdapterUpdater.html" > IGListAdapterUpdater< / a > < / code > . You can use your own layout and updater if you need advanced features!< / p >
2016-11-23 20:42:52 +00:00
< / blockquote >
2017-05-12 14:19:12 +00:00
< h3 id = 'connecting-the-data-source' class = 'heading' > Connecting the data source< / h3 >
2016-11-23 20:42:52 +00:00
2018-02-06 23:42:25 +00:00
< p > The last step is the < code > < a href = "Classes/IGListAdapter.html" > IGListAdapter< / a > < / code > ‘ s data source and returning some data.< / p >
2017-05-12 14:19:12 +00:00
< pre class = "highlight swift" > < code > < span class = "kd" > func< / span > < span class = "nf" > objects< / span > < span class = "p" > (< / span > < span class = "k" > for< / span > < span class = "nv" > listAdapter< / span > < span class = "p" > :< / span > < span class = "kt" > ListAdapter< / span > < span class = "p" > )< / span > < span class = "o" > -> < / span > < span class = "p" > [< / span > < span class = "kt" > ListDiffable< / span > < span class = "p" > ]< / span > < span class = "p" > {< / span >
2016-11-23 20:42:52 +00:00
< span class = "c1" > // this can be anything!< / span >
< span class = "k" > return< / span > < span class = "p" > [< / span > < span class = "s" > "Foo"< / span > < span class = "p" > ,< / span > < span class = "s" > "Bar"< / span > < span class = "p" > ,< / span > < span class = "mi" > 42< / span > < span class = "p" > ,< / span > < span class = "s" > "Biz"< / span > < span class = "p" > ]< / span >
< span class = "p" > }< / span >
2017-05-12 14:19:12 +00:00
< span class = "kd" > func< / span > < span class = "nf" > listAdapter< / span > < span class = "p" > (< / span > < span class = "n" > _< / span > < span class = "nv" > listAdapter< / span > < span class = "p" > :< / span > < span class = "kt" > ListAdapter< / span > < span class = "p" > ,< / span > < span class = "n" > sectionControllerFor< / span > < span class = "nv" > object< / span > < span class = "p" > :< / span > < span class = "kt" > Any< / span > < span class = "p" > )< / span > < span class = "o" > -> < / span > < span class = "kt" > ListSectionController< / span > < span class = "p" > {< / span >
2016-11-23 20:42:52 +00:00
< span class = "k" > if< / span > < span class = "n" > object< / span > < span class = "k" > is< / span > < span class = "kt" > String< / span > < span class = "p" > {< / span >
< span class = "k" > return< / span > < span class = "kt" > LabelSectionController< / span > < span class = "p" > ()< / span >
< span class = "p" > }< / span > < span class = "k" > else< / span > < span class = "p" > {< / span >
< span class = "k" > return< / span > < span class = "kt" > NumberSectionController< / span > < span class = "p" > ()< / span >
< span class = "p" > }< / span >
< span class = "p" > }< / span >
2017-05-12 14:19:12 +00:00
< span class = "kd" > func< / span > < span class = "nf" > emptyView< / span > < span class = "p" > (< / span > < span class = "k" > for< / span > < span class = "nv" > listAdapter< / span > < span class = "p" > :< / span > < span class = "kt" > ListAdapter< / span > < span class = "p" > )< / span > < span class = "o" > -> < / span > < span class = "kt" > UIView< / span > < span class = "p" > ?< / span > < span class = "p" > {< / span >
2016-11-23 20:42:52 +00:00
< span class = "k" > return< / span > < span class = "kc" > nil< / span >
< span class = "p" > }< / span >
< / code > < / pre >
2018-02-06 23:42:25 +00:00
< p > After you have created the data source you need to connect it to the < code > < a href = "Classes/IGListAdapter.html" > IGListAdapter< / a > < / code > by setting its < code > dataSource< / code > property:< / p >
2017-08-23 21:12:05 +00:00
< pre class = "highlight swift" > < code > < span class = "n" > adapter< / span > < span class = "o" > .< / span > < span class = "n" > dataSource< / span > < span class = "o" > =< / span > < span class = "k" > self< / span >
< / code > < / pre >
2018-02-06 23:42:25 +00:00
< p > You can return an array of < em > any< / em > type of data, as long as it conforms to < code > < a href = "Protocols/IGListDiffable.html" > IGListDiffable< / a > < / code > .< / p >
2017-05-12 14:19:12 +00:00
< h3 id = 'immutability' class = 'heading' > Immutability< / h3 >
2018-02-06 23:42:25 +00:00
< p > The data should be immutable. If you return mutable objects that you will be editing later, < code > IGListKit< / code > will not be able to diff the models accurately. This is because the instances have already been changed. Thus, the updates to the objects would be lost. Instead, always return a newly instantiated, immutable object and implement < code > < a href = "Protocols/IGListDiffable.html" > IGListDiffable< / a > < / code > .< / p >
2017-05-12 14:19:12 +00:00
< h2 id = 'diffing' class = 'heading' > Diffing< / h2 >
2016-11-23 20:42:52 +00:00
2017-05-12 14:19:12 +00:00
< p > < code > IGListKit< / code > uses an algorithm adapted from a paper titled < a href = "http://dl.acm.org/citation.cfm?id=359467&dl=ACM&coll=DL" > A technique for isolating differences between files< / a > by Paul Heckel. This algorithm uses a technique known as the < em > longest common subsequence< / em > to find a minimal diff between collections in linear time < code > O(n)< / code > . It finds all < strong > inserts< / strong > , < strong > deletes< / strong > , < strong > updates< / strong > , and < strong > moves< / strong > between arrays of data.< / p >
2016-11-23 20:42:52 +00:00
2018-02-06 23:42:25 +00:00
< p > To add custom, diffable models, you need to conform to the < code > < a href = "Protocols/IGListDiffable.html" > IGListDiffable< / a > < / code > protocol and implement < code > diffIdentifier()< / code > and < code > isEqual(toDiffableObject:)< / code > .< / p >
2016-11-23 20:42:52 +00:00
2017-08-23 21:12:05 +00:00
< blockquote >
< p > < strong > Note:< / strong > an object’ s < code > diffIdentifier()< / code > should never change. If an object mutates it’ s < code > diffIdentifer()< / code > the behavior of IGListKit is undefined (and almost assuredly undesirable).< / p >
< / blockquote >
2016-11-23 20:42:52 +00:00
< p > For an example, consider the following model:< / p >
< pre class = "highlight swift" > < code > < span class = "kd" > class< / span > < span class = "kt" > User< / span > < span class = "p" > {< / span >
< span class = "k" > let< / span > < span class = "nv" > primaryKey< / span > < span class = "p" > :< / span > < span class = "kt" > Int< / span >
< span class = "k" > let< / span > < span class = "nv" > name< / span > < span class = "p" > :< / span > < span class = "kt" > String< / span >
< span class = "c1" > // implementation, etc< / span >
< span class = "p" > }< / span >
< / code > < / pre >
< p > The user’ s < code > primaryKey< / code > uniquely identifies user data, and the < code > name< / code > is just the value for that user.< / p >
< p > Let’ s say a server returns a < code > User< / code > object that looks like this:< / p >
< pre class = "highlight swift" > < code > < span class = "k" > let< / span > < span class = "nv" > shayne< / span > < span class = "o" > =< / span > < span class = "kt" > User< / span > < span class = "p" > (< / span > < span class = "nv" > primaryKey< / span > < span class = "p" > :< / span > < span class = "mi" > 2< / span > < span class = "p" > ,< / span > < span class = "nv" > name< / span > < span class = "p" > :< / span > < span class = "s" > "Shayne"< / span > < span class = "p" > )< / span >
< / code > < / pre >
< p > But sometime after the client receives < code > shayne< / code > , someone changes their name:< / p >
< pre class = "highlight swift" > < code > < span class = "k" > let< / span > < span class = "nv" > ann< / span > < span class = "o" > =< / span > < span class = "kt" > User< / span > < span class = "p" > (< / span > < span class = "nv" > primaryKey< / span > < span class = "p" > :< / span > < span class = "mi" > 2< / span > < span class = "p" > ,< / span > < span class = "nv" > name< / span > < span class = "p" > :< / span > < span class = "s" > "Ann"< / span > < span class = "p" > )< / span >
< / code > < / pre >
< p > Both < code > shayne< / code > and < code > ann< / code > represent the same < em > unique< / em > data because they share the same < code > primaryKey< / code > , but they are not < em > equal< / em > because their names are different.< / p >
2018-02-06 23:42:25 +00:00
< p > To represent this in < code > IGListKit< / code > ’ s diffing, add and implement the < code > < a href = "Protocols/IGListDiffable.html" > IGListDiffable< / a > < / code > protocol:< / p >
< pre class = "highlight swift" > < code > < span class = "kd" > extension< / span > < span class = "kt" > User< / span > < span class = "p" > :< / span > < span class = "kt" > ListDiffable< / span > < span class = "p" > {< / span >
2016-11-23 20:42:52 +00:00
< span class = "kd" > func< / span > < span class = "nf" > diffIdentifier< / span > < span class = "p" > ()< / span > < span class = "o" > -> < / span > < span class = "kt" > NSObjectProtocol< / span > < span class = "p" > {< / span >
< span class = "k" > return< / span > < span class = "n" > primaryKey< / span >
< span class = "p" > }< / span >
< span class = "kd" > func< / span > < span class = "nf" > isEqual< / span > < span class = "p" > (< / span > < span class = "n" > toDiffableObject< / span > < span class = "nv" > object< / span > < span class = "p" > :< / span > < span class = "kt" > Any< / span > < span class = "p" > ?)< / span > < span class = "o" > -> < / span > < span class = "kt" > Bool< / span > < span class = "p" > {< / span >
< span class = "k" > if< / span > < span class = "k" > let< / span > < span class = "nv" > object< / span > < span class = "o" > =< / span > < span class = "n" > object< / span > < span class = "k" > as?< / span > < span class = "kt" > User< / span > < span class = "p" > {< / span >
< span class = "k" > return< / span > < span class = "n" > name< / span > < span class = "o" > ==< / span > < span class = "n" > object< / span > < span class = "o" > .< / span > < span class = "n" > name< / span >
< span class = "p" > }< / span >
< span class = "k" > return< / span > < span class = "kc" > false< / span >
< span class = "p" > }< / span >
< span class = "p" > }< / span >
< / code > < / pre >
< p > The algorithm will skip updating two < code > User< / code > objects that have the same < code > primaryKey< / code > and < code > name< / code > , even if they are different instances! You now avoid unnecessary UI updates in the collection view even when providing new instances.< / p >
< blockquote >
< p > < strong > Note:< / strong > Remember that < code > isEqual(toDiffableObject:)< / code > should return < code > false< / code > when you want to reload the cells in the corresponding section controller.< / p >
< / blockquote >
2017-05-12 14:19:12 +00:00
< h3 id = 'diffing-outside-of-iglistkit' class = 'heading' > Diffing outside of IGListKit< / h3 >
2016-11-23 20:42:52 +00:00
2018-02-06 23:42:25 +00:00
< p > If you want to use the diffing algorithm outside of < code > < a href = "Classes/IGListAdapter.html" > IGListAdapter< / a > < / code > and < code > UICollectionView< / code > , you can! The diffing algorithm was built with the flexibility to be used with any models that conform to < code > < a href = "Protocols/IGListDiffable.html" > IGListDiffable< / a > < / code > .< / p >
2017-05-12 14:19:12 +00:00
< pre class = "highlight swift" > < code > < span class = "k" > let< / span > < span class = "nv" > result< / span > < span class = "o" > =< / span > < span class = "kt" > ListDiff< / span > < span class = "p" > (< / span > < span class = "nv" > oldArray< / span > < span class = "p" > :< / span > < span class = "n" > oldUsers< / span > < span class = "p" > ,< / span > < span class = "nv" > newArray< / span > < span class = "p" > :< / span > < span class = "n" > newUsers< / span > < span class = "p" > ,< / span > < span class = "o" > .< / span > < span class = "n" > equality< / span > < span class = "p" > )< / span >
2016-11-23 20:42:52 +00:00
< / code > < / pre >
< p > With this you have all of the deletes, reloads, moves, and inserts! There’ s even a function to generate < code > NSIndexPath< / code > results.< / p >
2017-05-12 14:19:12 +00:00
< h2 id = 'advanced-features' class = 'heading' > Advanced Features< / h2 >
< h3 id = 'working-range' class = 'heading' > Working Range< / h3 >
2016-11-23 20:42:52 +00:00
< p > A < em > working range< / em > is a range of section controllers who aren’ t yet visible, but are near the screen. Section controllers are notified of their entrance and exit to this range. This concept lets your section controllers < strong > prepare content< / strong > before they come on screen (e.g. download images).< / p >
2018-02-06 23:42:25 +00:00
< p > The < code > < a href = "Classes/IGListAdapter.html" > IGListAdapter< / a > < / code > must be initialized with a range value in order to work. This value is a multiple of the visible height or width, depending on the scroll-direction.< / p >
2017-05-12 14:19:12 +00:00
< pre class = "highlight swift" > < code > < span class = "k" > let< / span > < span class = "nv" > adapter< / span > < span class = "o" > =< / span > < span class = "kt" > ListAdapter< / span > < span class = "p" > (< / span > < span class = "nv" > updater< / span > < span class = "p" > :< / span > < span class = "kt" > ListAdapterUpdater< / span > < span class = "p" > (),< / span >
< span class = "nv" > viewController< / span > < span class = "p" > :< / span > < span class = "k" > self< / span > < span class = "p" > ,< / span >
< span class = "nv" > workingRangeSize< / span > < span class = "p" > :< / span > < span class = "mi" > 1< / span > < span class = "p" > )< / span > < span class = "c1" > // 1 before/after visible objects< / span >
2016-11-23 20:42:52 +00:00
< / code > < / pre >
2023-02-09 02:34:25 +00:00
< p > < img src = "https://raw.githubusercontent.com/Instagram/IGListKit/main/Resources/workingrange.png" alt = "working-range" > < / p >
2016-11-23 20:42:52 +00:00
< p > You can set the weak < code > workingRangeDelegate< / code > on a section controller to receive events.< / p >
2017-05-12 14:19:12 +00:00
< h3 id = 'supplementary-views' class = 'heading' > Supplementary Views< / h3 >
2016-11-23 20:42:52 +00:00
2018-02-06 23:42:25 +00:00
< p > Adding supplementary views to section controllers is as simple as setting the (weak) < code > supplementaryViewSource< / code > and implementing the < code > < a href = "Protocols/IGListSupplementaryViewSource.html" > IGListSupplementaryViewSource< / a > < / code > protocol. This protocol works nearly the same as returning and configuring cells.< / p >
2017-05-12 14:19:12 +00:00
< h3 id = 'display-delegate' class = 'heading' > Display Delegate< / h3 >
2016-11-23 20:42:52 +00:00
< p > Section controllers can set the weak < code > displayDelegate< / code > delegate to an object, including < code > self< / code > , to receive display events about a section controller and individual cells.< / p >
2017-05-12 14:19:12 +00:00
< h3 id = 'custom-updaters' class = 'heading' > Custom Updaters< / h3 >
2016-11-23 20:42:52 +00:00
2018-02-06 23:42:25 +00:00
< p > The default < code > < a href = "Classes/IGListAdapterUpdater.html" > IGListAdapterUpdater< / a > < / code > should handle any < code > UICollectionView< / code > update that you need. However, if you find the functionality lacking, or want to perform updates in a very specific way, you can create an object that conforms to the < code > < a href = "Protocols/IGListUpdatingDelegate.html" > IGListUpdatingDelegate< / a > < / code > protocol and initialize a new < code > < a href = "Classes/IGListAdapter.html" > IGListAdapter< / a > < / code > with it.< / p >
2016-11-23 20:42:52 +00:00
2018-02-06 23:42:25 +00:00
< p > Check out the updater < code > < a href = "Classes.html#/c:objc(cs)IGListReloadDataUpdater" > IGListReloadDataUpdater< / a > < / code > (used in unit tests) for an example.< / p >
2016-11-23 20:42:52 +00:00
< / section >
< / section >
< section id = "footer" >
2023-04-07 07:23:43 +00:00
< p > © 2023 < a class = "link" href = "https://twitter.com/MetaOpenSource" target = "_blank" rel = "external noopener" > Instagram< / a > . All rights reserved. (Last updated: 2023-04-07)< / p >
< p > Generated by < a class = "link" href = "https://github.com/realm/jazzy" target = "_blank" rel = "external noopener" > jazzy ♪♫ v0.14.3< / a > , a < a class = "link" href = "https://realm.io" target = "_blank" rel = "external noopener" > Realm< / a > project.< / p >
2016-11-23 20:42:52 +00:00
< / section >
< / article >
< / div >
< / body >
< / html >