How to create UICollectionView using Swift without storyboards

There’s a lot of tutorials about how to create a UICollectionView using storyboards or just nib files. I don’t like Interface Builder and prefer to do everything in code. Most of the time it’s easier, it creates less bugs, so in this tutorial we will create UICollectionView programmatically.

UICollectionView is highly customizable class for presenting your content in almost any layout you want. If you want Apple to tell you basics about it, visit WWDC 2012 videos “Introducing Collection Views” and “Advanced Collection Views and Building Custom Layouts”. It implements in a similar way to UITableView — using UICollectionViewDataSource and UICollectionViewDelegate protocols. Let’s take a look at how to do it using Swift.

Let the show begin

At the time of writing this post, Xcode 6 is in beta so I can’t post screenshots of it, but don’t worry, you don’t need them because we’ll do almost everything in code.

Create an Xcode project. Unfortunately, Xcode 6 doesn’t allow us to choose an empty project with only an App Delegate, so we’ll choose one close to it. Select Single View Application and click Next. Name your project as you want (I named it Gridtest), select iPhone in Devices list, but actually this will work just fine on iPad too (not two :)). Uncheck Use Core Data. And do not forget to select Swift in Language list!

Ok, so here’s our project. The next step is optional, but it may be useful to know. Let’s…

Say goodbye to storyboard

I want to do everything in code, so let’s delete the storyboard that was provided to us by Xcode.

Open up Project Navigator (⌘1).

Select your project here, then in menu at the right of this project button under the Targets section select your project name. It’s Gridtest in my case.

Clear Main Interface field.

Delete Main.storyboard from your project.

Alright. There’s no storyboards now, but because of this now we need to initialize a window programmatically, just like in Objective-C. Select AppDelegate.swift in Project Navigator and update application(_:didFinishLaunchingWithOptions:) method with this code:

This little piece of code (as the name tells us) gets called right after application finish its initialization process. Here we initialize our window property, set it’s background color to be red, set an instance of ViewController class to be window’s root view controller and show it to user. Window is where everything is displayed in an iOS application.

Run the app and you will see that the screen is filled with red. Good. Window is here, so we can move on. An instance of ViewController class is a root view controller of our window, but it’s transparent. Let’s fill it with UICollectionView!

Collection View

UICollectionView is a nice thing, but it’s pretty easy to get confused when you work with it for the first time. Lots of links in Google tell different information, but it’s cool that you have clicked on a link to Randexdev 🙂

Apple provides us with UICollectionViewFlowLayout — grid-like layout for cells in our collection view. To create nice layouts people subclass this class or UICollectionViewLayout. We don’t need to subclass anything, but if you want it’s up to you. To fully implement UICollectionView with UICollectionViewFlowLayout, we need to adopt three protocols (not 2, like in UITableView): UICollectionViewDataSource, UICollectionViewDelegate, and UICollectionViewDelegateFlowLayout.

Well, wut?! We need to adopt three protocols, why there’s only two? This is because UICollectionViewDelegateFlowLayout inherits from UICollectionViewDelegate, so by writing only UICollectionViewDelegateFlowLayout we adopt both of them. By the way, if you’d need to implement UIScrollViewDelegate methods in your project, by writing UICollectionViewDelegateFlowLayout you automatically adopt UIScrollViewDelegate too.

Don’t worry if you get an error here, we’ll fix that soon. Right after class declaration create a new variable:

var collectionView: UICollectionView!

This creates our first and last variable we need. As you can see, this is an instance of UICollectionView class, and this is an explicitly unwrapped optional (because there’s and exclamation mark after the class name). Explicitly unwrapped optionals are dangerous, because if you try to use one before it gets initialized, your app will crash. We could remove the exclamation mark, making this variable just a simple non-optional, but then we’d need to initialize it in the class’ init methods. I want to simplify this tutorial, so I won’t do it. Let’s initialize our collection view in viewDidLoad() method.

At first, we create an instance of UICollectionViewFlowLayout because you can’t initialize UICollectionView without a layout — you’ll simply get an exception. Then we set sectionInset just to make our grid more beautiful. 20 instead of 10 for top inset because of the status bar. Then we set our cell size. If it’s not set, cells will be with a default size of 50×50. After this we finally initialize our collectionView, tell him that we will be his dataSource and delegate. Then we register a class that will represent a cell in our collection view. Important: this is necessary to register your cell class because without this you’ll get an exception, because collection view need to know what kind of cells it works with. In our case we didn’t create any custom cells, so we just register a UICollectionViewCell class as a class for our cells.

And at last we need to implement dataSource methods. Write them somewhere in ViewController class. I’ve used to do it at the bottom.

CollectionView(_:numberOfItemsInSection:) must return number of items to be displayed on screen. It is similar to UITableView‘s numberOfRowsInSection(_:). In collectonView(_:cellForItemAtIndexPath:) you need to create a cell and return it. The thing is, dequeueReusableCellWithReuseIdentifier(_:forIndexPath:) dequeues existing cell if available or creates a new one based on a class you’ve registered. That’s why you should’ve register a class previously. At last, cells of UICollectionViewCell class doesn’t contain anything at all, so we just set a backgroundColor to them.

Run the app and you’ll see that everything is working fine. You should see a grid with several columns and 14 orange rectangles in it on a white background. Congratulations!

Where to go from here?

Check out the UICollectionViewdocumentation, experiment, explore new things and optional methods in protocols we’ve adopted. UICollectionView is very flexible and powerful instrument to show your content to user, so you better take a closer look.

If you have a question, suggestion, or if I did something wrong here, please let me now in comments below.

There are so many Swift examples online that overcomplicate things and don’t explain important steps. Your article could not be have been better written – clear, simple, and straight to the point. Thanks!

thanks for this page. I started getting errors relating to the UICollectionViewDataSource protocol after upgrading to Xcode 6 build 7 and was able to fix them after checking your code. I had to remove a few ‘!’s…

Thanks for the nice tutorial, I followed every step but I am not able to see collection view added to my view.
The only difference is I am trying to add a collection view in custom keyboard extension.
Do I need to do anything different in case of custom keyboard extension?

This is great and great, but I got an error when doing it in a storyboard about being unable to dequeue something something reuse something something. All I had to do to fix it was move the collectionView.registerClass(…) command two lines up, so it came before setting the dataSource and the delegate on the collectionView.

If you made that change here too, others wouldn’t encounter that error.