IGListKit

5.0.0

A data-driven UICollectionView framework for building fast and flexible lists.
Instagram/IGListKit

What's New

5.0.0

2024-05-13T07:11:15Z

5.0.0 is finally here! 🎉🎊🥳

This version brings all of the enhancements Instagram has been adding to IGListKit over the years since 4.0.0. We're incredibly excited for everyone to try it out and let us know what they think. If you encounter any issues, please let us know by opening a GitHub ticket. Thank you so much to all of the internal and external contributors who submitted code, reported issues and everything else that made this release possible.

Breaking Changes

  • Changed iOS deployment target to 11.0 and macOS deployment target to 10.13 Kent Sutherland (#1573)

  • Removed unneeded diffing functions IGListDiffExperiment(...) and IGListDiffPathsExperiment(...). Maxime Ollivier (254c041)

  • ListSectionController.collectionContext and ListGenericSectionController.object are now implicitly-unwrapped optionals in Swift. Nate Stedman (a6526ce)

  • The argument of IGListGenericSectionController's -didUpdateToObject: is now generic, not id. Nate Stedman (a6526ce)

  • Updated IGListUpdatingDelegate, including a new method to safely perform [IGListAdapter setDataSource:] and changes to -performUpdateWithCollectionViewBlock that allows section-controllers to be created before the diffing (and therefore use a more accurate toObjects array) Maxime Ollivier (43af883)

// OLD
- (void)performUpdateWithCollectionViewBlock:(IGListCollectionViewBlock)collectionViewBlock
                                 fromObjects:(nullable NSArray<id <IGListDiffable>> *)fromObjects
                              toObjectsBlock:(nullable IGListToObjectBlock)toObjectsBlock
                                    animated:(BOOL)animated
                       objectTransitionBlock:(IGListObjectTransitionBlock)objectTransitionBlock
                                  completion:(nullable IGListUpdatingCompletion)completion;

// NEW
- (void)performUpdateWithCollectionViewBlock:(IGListCollectionViewBlock)collectionViewBlock
                                    animated:(BOOL)animated
                            sectionDataBlock:(IGListTransitionDataBlock)sectionDataBlock
                       applySectionDataBlock:(IGListTransitionDataApplyBlock)applySectionDataBlock
                                  completion:(nullable IGListUpdatingCompletion)completion;

// NEW
- (void)performDataSourceChange:(IGListDataSourceChangeBlock)block;
  • Removed allowsBackgroundReloading from IGListAdapterUpdater because it's causing performance issues and other bugs. Maxime Ollivier (032e1b0)

  • Introducing allowsBackgroundDiffing on IGListAdapterUpdater! This property lets the updater perform the diffing on a background thread. Originally introduced by Ryan Nystrom a while back. Maxime Ollivier (9a11f6)

  • Updated scrollToObject: method in IGListAdapter to include a new parameter additionalOffset to handle shifting the final scroll position by some vertical or horizontal offset depending on the scroll direction. This allows the object to be shown at the correct position when it is scrolled to in a list with sticky headers. Anna Tang (f2166c3)

// OLD
- (void)scrollToObject:(id)object
    supplementaryKinds:(nullable NSArray<NSString *> *)supplementaryKinds
       scrollDirection:(UICollectionViewScrollDirection)scrollDirection
        scrollPosition:(UICollectionViewScrollPosition)scrollPosition
              animated:(BOOL)animated;

// NEW
- (void)scrollToObject:(id)object
    supplementaryKinds:(nullable NSArray<NSString *> *)supplementaryKinds
       scrollDirection:(UICollectionViewScrollDirection)scrollDirection
        scrollPosition:(UICollectionViewScrollPosition)scrollPosition
      additionalOffset:(CGPoint)additionalOffset
              animated:(BOOL)animated;
  • Unshipped the IGListExperimentSkipViewSectionControllerMap experiment as it was no longer being used. Maxime Ollivier (99e24af)

  • Unshipped the IGListExperimentSkipPerformUpdateIfPossible experiment since it wasn't considered safe enough. Maxime Ollivier (b3a22ad)

Enhancements

  • Added traitCollection property to IGListAdapter in order to access the current trait collection of the underlying collection view. Sash Zats (53a96a9)

  • Added viewForSupplementaryElementOfKind:atIndex:sectionController: to IGListAdapter. ryanmathews (c708a10)

  • Replaced usage of method_exchangeImplementations with class_replaceMethod for increased performance. Saagar Jha (#1583)

  • Added shouldDeselectItemAtIndex: to IGListSectionController. bladeofky (b22a10e)

  • Added shouldSelectItemAtIndex: to IGListSectionController. dirtmelon (#1479)

  • Added Mac Catalyst support. Petro Rovenskyy (#1487)

  • Introduce IGListSwiftKit, with Swift refinements for dequeueReusableCellOfClass methods. Koen Punt (#1388).

  • Added APPLICATION_EXTENSION_API_ONLY support for IGListDiffKit Peter Meyers (#1422)

  • Improved performance by deferring requesting objects from the IGListAdapterDataSource until just before diffing is executed. If n updates are coalesced into one, this results in just a single request for objects from the data source. Shipped with experiment IGListExperimentDeferredToObjectCreation from Ryan Nystrom. Maxime Ollivier (7fc4384)

  • Improved performance by using reloadData when there are too many diffing updates. Shipped with experiment IGListExperimentReloadDataFallback from Ryan Nystrom. Maxime Ollivier (86ecc60)

  • Small performance improvement by replacing NSSet with NSArray during the data update to avoid unnecessary hashing, especially when dealing with lots of large objects with non trivial hashes. Maxime Ollivier (c0cf10d)

  • Lazy initialize the -emptyViewForListAdapter: Maxime Ollivier (29d4640)

  • Updated IGListAdapterUpdater to be safer, more performant, and better organized! Maxime Ollivier (247e7ca)

    • Safely handles [IGListAdapter setDataSource:] by also invalidating the UICollectionView data.
    • Safely handles [IGListAdapter setCollectionView:] by cancelling on-going transactions.
    • Safely handles returning nil IGListSectionController from IGListAdapterDataSource by dumping objects that don't have a controller before the diffing.
    • Checks that the UICollectionView section count matches the IGListAdapter before committing the update, otherwise fallback to a reload.
    • Schedules an update block (dispatch_async) only when needed, instead of scheduling on every single call to -performUpdateWithCollectionViewBlock.
    • Wraps each update in a transaction that can be easily cancelled.
    • Uses methods instead of blocks to make the callstack easier to read in crash reports.
    • Unblocks IGListExperimentBackgroundDiffing
  • The IGListExperimentFixCrashOnReloadObjects experiment succeeded and has officially been implemented into IGListKit. Maxime Ollivier (99e24af)

  • Added IGListExperimentKeepPointerToCollectionViewDataSource experiment as a potential solution for certain crashes being periodically observed.

  • Added IGListExperimentDisableAnimationOnUpdates experiment to optionally disable update animations in IGListAdapter instances. (eeb5208)

Fixes

  • Don't crash if you use IGListSectionController without a subclass Maxime Ollivier (6ea2b91)

  • Testing crash fix when calling -[IGListAdapter reloadObjects ...] during an update Maxime Ollivier (cd3f84f)

  • Repaired Swift Package Manager support. Petro Rovenskyy (#1487)

  • IGListCollectionViewLayout should get the section/index counts via UICollectionView to stay in sync, instead of the dataSource Maxime Ollivier (677ce77)

  • Remove [collectionView layoutIfNeeded] before scrolling in [IGListAdapter scrollToObject...] to avoid creating off-screen cells. Maxime Ollivier (ea03bc9)

  • Remove [collectionView layoutIfNeeded] before updating in [IGListAdapterUpdater performBatchUpdates...] to fix occasional glitches. Maxime Ollivier (aca18c7)

  • Fixed IGListAdapterUpdaterDelegate by 1) calling willReloadDataWithCollectionView on fallback reloads and 2) making sure willPerformBatchUpdatesWithCollectionView is only called when performing a batch update. Maxime Ollivier (29bf582)

  • Fixed missing update when calling performUpdatesAnimated multiple times quickly and using the reloadDataFallback(). Maxime Ollivier (a70d2d7)

  • Request the UICollectionView until just-before we update. This way if the UICollectionView is changed between update-queue and execution, we guarantee the update is performed on the correct view. Ship with experiment IGListExperimentGetCollectionViewAtUpdate from Ryan Nystrom. Maxime Ollivier (34c935c)

  • Fixed unsigned integer overflow handling in IGListBatchUpdateData Jason Hsu (#1299)

  • Fixed when collection views wouldn't recalculate its layout when its bound changes. Sash Zats (d220f8a)

  • Fixed when calling invalidateLayout on IGListCollectionViewLayout wouldn't perform layout recalculation. Tim Oliver (ffd51e6)

Build Status Coverage Status Pods Version Platforms Carthage Compatible


A data-driven UICollectionView framework for building fast and flexible lists.

Main Features
🙅 Never call performBatchUpdates(_:, completion:) or reloadData() again
🏠 Better architecture with reusable cells and components
🔠 Create collections with multiple data types
🔑 Decoupled diffing algorithm
Fully unit tested
🔍 Customize your diffing behavior for your models
📱 Simply UICollectionView at its core
🚀 Extendable API
🐦 Written in Objective-C with full Swift interop support

IGListKit is built and maintained with ❤️ by Instagram engineering. We use the open source version main branch in the Instagram app.

Multilingual translation

Chinese README

Requirements

  • Xcode 11.0+
  • iOS 11.0+
  • tvOS 11.0+
  • macOS 10.13+ (diffing algorithm components only)
  • Interoperability with Swift 3.0+

Installation

CocoaPods

The preferred installation method is with CocoaPods. Add the following to your Podfile:

pod 'IGListKit', '~> 4.0.0'

Carthage

For Carthage, add the following to your Cartfile:

github "Instagram/IGListKit" ~> 4.0.0

Swift Package Manager

For Swift Package Manager:

To integrate using Xcode:

File -> Swift Packages -> Add Package Dependency

Enter package URL: https://github.com/Instagram/IGListKit, and select the latest release.

For advanced usage, see our Installation Guide.

Getting Started

Try out IGListKit by opening any of the sample apps available in the Examples directory.

Documentation

You can find the docs here. Documentation is generated with jazzy and hosted on GitHub-Pages.

To regenerate docs, run ./scripts/build_docs.sh from the root directory in the repo.

Vision

For the long-term goals and "vision" of IGListKit, please read our Vision doc.

Contributing

Please see the CONTRIBUTING file for how to help. At Instagram, we sync the open source version of IGListKit daily, so we're always testing the latest changes. But that requires all changes be thoroughly tested and follow our style guide.

We have a set of starter tasks that are great for beginners to jump in on and start contributing.

License

IGListKit is MIT-licensed.

The files in the /Examples/ directory are licensed under a separate license as specified in each file. Documentation is licensed CC-BY-4.0.

Legal

Copyright © Meta Platforms, Inc • Terms of UsePrivacy Policy

Description

  • Swift Tools 5.0.0
View More Packages from this Author

Dependencies

  • None
Last updated: Fri Jun 21 2024 12:35:44 GMT-0900 (Hawaii-Aleutian Daylight Time)