IGListKit Tutorial: Better UICollectionViews
In this IGListKit tutorial, you’ll learn to build better, more dynamic UICollectionViews with Instagram’s data-driven framework. By Ron Kliffer.
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress, bookmark, personalise your learner profile and more!
Create accountAlready a member of Kodeco? Sign in
Contents
IGListKit Tutorial: Better UICollectionViews
30 mins
Each app starts off the same way: a few screens, some buttons and maybe a list or two. But as time goes on and the app grows, features start to creep their way in. Your clean data sources start to crumble under the pressure of deadlines and product managers. After a while, you’re left with the massive view controller ruins to maintain. Lucky for you, there’s a solution to that problem!
Instagram created IGListKit to make feature creep and massive view controllers a thing of the past when working with UICollectionView
. By creating lists with IGListKit, you can build apps with decoupled components, blazing-fast updates and support for any type of data.
In this tutorial you will refactor a basic UICollectionView
to use IGListKit, then extend the app and take it out of this world!
Getting Started
You are one of NASA’s top software engineers and on staff for the latest manned mission to Mars. The team already built the first version of the Marslink app.
Use the Download Materials button at the top or bottom of this tutorial to download it. After you’ve downloaded the project, open Marslink.xcworkspace, then build and run the app.
So far, the app just shows a list of astronaut journal entries.
You’re tasked with adding new features to this app whenever the crew needs them. Familiarize yourself with the project by opening ClassicFeedViewController.swift and having a look around.
If you’ve ever worked with UICollectionView
, what you see looks pretty standard:
-
ClassicFeedViewController
is aUIViewController
subclass that implementsUICollectionViewDataSource
in an extension. -
viewDidLoad()
creates aUICollectionView
, registers cells, sets the data source and adds it to the view hierarchy. - The
loader.entries
array powers the number of sections, each having just two cells (one for the date and one for the text). - Date cells contain the Sol date and text entry cells with
Journal
text. -
collectionView(_:layout:sizeForItemAt:)
returns a fixed size for the date cell and calculates the size of the text for the actual entry.
Everything seems to be working just fine, but the mission director comes up with some urgent product update requests:
An astronaut has just become stranded on Mars. We need you to add a weather module and real-time chat. You have 48 hours.
An astronaut has just become stranded on Mars. We need you to add a weather module and real-time chat. You have 48 hours.
Engineers from JPL have some of these systems working, but they need your help adding them to the app.
If all the pressure of bringing an astronaut home wasn’t enough, NASA’s head designer just handed you requirements that each subsystem’s update in the app has to be animated, which means no reloadData()
.
How in the world are you supposed to integrate these new modules into an existing app and make all the transitions animated? The astronaut only has so many potatoes!
Introducing IGListKit
While UICollectionView
is an incredibly powerful tool, with great power comes great responsibility. Keeping your data source and the view in sync is of utmost importance, but disconnects here commonly cause crashes.
IGListKit is a data-driven UICollectionView
framework built by the team at Instagram. With this framework, you provide an array of objects to display in UICollectionView
. For each type of object, an adapter creates something called a section controller, which has all of the details for creating cells.
IGListKit automatically diffs your objects and performs animated batch updates on the UICollectionView
for whatever changed. This way you never have to write batch updates yourself, avoiding the issues listed under caveats here.
Adding IGListKit to a UICollectionView
IGListKit does all the hard work of identifying changes in a collection and updating the appropriate rows with animation. It is also structured to easily handle multiple sections with different data and UI. With that in mind, it’s a perfect solution to the new batch of requirements—so it’s time to start implementing it!
With Marslink.xcworkspace still open, right-click on the ViewControllers group and select New File. Add a new Cocoa Touch Class that subclasses UIViewController named FeedViewController and ensure the language is set to Swift.
Open AppDelegate.swift and find application(_:didFinishLaunchingWithOptions:)
. Find the line that pushes ClassicFeedViewController()
onto the navigation controller, and replace it with this:
nav.pushViewController(FeedViewController(), animated: false)
FeedViewController
is now the root view controller. You’ll keep ClassicFeedViewController.swift around for reference, but FeedViewController
is where you’ll implement the new IGListKit-powered collection view.
Build and run and make sure a new, empty view controller shows up on screen.
Adding the Journal Loader
Open FeedViewController.swift and add the following property to the top of FeedViewController
:
let loader = JournalEntryLoader()
JournalEntryLoader
is a class that loads hard-coded journal entries into an entries
array.
Add the following to the bottom of viewDidLoad()
:
loader.loadLatest()
loadLatest()
is a JournalEntryLoader
method that loads the latest journal entries.
Adding the Collection View
It’s time to start adding some IGListKit-specific controls to the view controller. Before you do, you need to import the framework. Near the top of FeedViewController.swift, add a new import:
import IGListKit
#import
into your bridging header.
Add an initialized collectionView
constant to the top of FeedViewController
:
// 1
let collectionView: UICollectionView = {
// 2
let view = UICollectionView(
frame: .zero,
collectionViewLayout: UICollectionViewFlowLayout())
// 3
view.backgroundColor = .black
return view
}()
Here’s what this code does:
- IGListKit uses a regular
UICollectionView
and adds its own functionality on top of it, as you will see later on. - Start with a zero-sized rect, since the view isn’t created yet. It uses a
UICollectionViewFlowLayout
just as theClassicFeedViewController
did. - Set the background color to NASA-approved black.
Add the following to the bottom of viewDidLoad()
:
view.addSubview(collectionView)
This adds the new collectionView
to the controller’s view.
Below viewDidLoad()
, add the following:
override func viewDidLayoutSubviews() {
super.viewDidLayoutSubviews()
collectionView.frame = view.bounds
}
This overrides viewDidLayoutSubviews()
, setting the collectionView
frame to match the view
bounds.