UICollectionView custom cell layout: how to define a custom cell with swift

In this tutorial you'll learn how to define an UICollectionView custom cell layout for iOS 8 with swift. You'll see the basic steps for defining a collection view, a custom cell layout and data loading from url using the JSON format.

This is the example for the custom UICollectionView that you'll obtain using Swift:


Let's create a new iOS single view project.


Layout Definition

Select the main.storyboard, disable the use size classes feauture and put inside the UIViewController a UICollectionView. Select the UICollectionView and under the attribute inspector set the background color to white.

CollectionView Swift

Select now the cell inside the UIViewController and set a custom size of 50x100.

Put inside the UiCollectionView Cell two UILabel one below the other and set the constraints.

Create a new ios cocoa touch class. Call it CustomCell subclass of UICollectionViewCell.

Turn back to the main.storyboard, select the UICollectionViewCell and under the identity inspector set the CustomCell custom class. Under the Attribute inspector set Cell as  identifier name.

Open now the assistant editor. We'll assign now the variables to the view elements. Select the UICollectionView, by holding the CTRL key drag the element into the ViewController.swift class. Put as a variable name collectionview. Do the same thing for the UILabel elements inside the cell. Assign to the CustomCell class the variables text and country respectively.


Load data from JSON and CollectionView definition

Open now the ViewController.swift file, on the right of the class name append the needed subclasses UICollectionViewDataSource and UICollectionViewDelegate.

import UIKit

class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate {

    @IBOutlet var collectionview: UICollectionView!
    struct country
        var country:String
        var code:String
        init(code:String, country:String)
            self.country = country
            self.code = code
    var Data:Array<  country > = Array < country >()

    override func viewDidLoad() {
	//initialize the collection view

        collectionview.dataSource = self
        collectionview.delegate = self
        let layout:UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top:1,left:10,bottom:10,right:10)
        layout.minimumInteritemSpacing = 5
        layout.minimumLineSpacing = 10

        collectionview.collectionViewLayout = layout

	//call the load data from json function


Let's define now the collectionview cell size, elements number and content

 func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell
        var cell = collectionView.dequeueReusableCellWithReuseIdentifier("Cell", forIndexPath: indexPath) as! CustomCell
        var bcolor : UIColor = UIColor( red: 0.2, green: 0.2, blue:0.2, alpha: 0.3 )
        cell.layer.borderColor = bcolor.CGColor
        cell.layer.borderWidth = 0.5
        cell.layer.cornerRadius = 3
        cell.text.text = Data[indexPath.row].code
        cell.country.text = Data[indexPath.row].country
        return cell

    func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int
       return Data.count
    func collectionView(collectionView: UICollectionView,
        layout collectionViewLayout: UICollectionViewLayout,
        sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {

            return CGSize(width: 100  , height: 50)

Now the function for loading the data from URL and extracting the information from the json format are defined. If you want to read a more detailed tutorial about the json format, read Swift UITableView: Load data from JSON.

  func extract_json(data:NSString)
        var parseError: NSError?
        let jsonData:NSData = data.dataUsingEncoding(NSASCIIStringEncoding)!
        let json: AnyObject? = NSJSONSerialization.JSONObjectWithData(jsonData, options: nil, error: &parseError)
        if (parseError == nil)
            if let countries_list = json as? NSArray
                for (var i = 0; i < countries_list.count ; i++ )
                    if let country_obj = countries_list[i] as? NSDictionary
                        if let country_name = country_obj["country"] as? String
                            if let country_code = country_obj["code"] as? String
                                var add_it = country(code: country_code, country: country_name)

    func do_refresh()
        dispatch_async(dispatch_get_main_queue(), {
    func get_data_from_url(url:String)
        let httpMethod = "GET"
        let timeout = 15
        let url = NSURL(string: url)
        let urlRequest = NSMutableURLRequest(URL: url!,
            cachePolicy: .ReloadIgnoringLocalAndRemoteCacheData,
            timeoutInterval: 15.0)
        let queue = NSOperationQueue()
            queue: queue,
            completionHandler: {(response: NSURLResponse!,
                data: NSData!,
                error: NSError!) in
                if data != nil && error == nil{
                    let json = NSString(data: data, encoding: NSASCIIStringEncoding)


Collection View Header Section

Let's now add the header section to the UICollectionView. Turn back to the main.storyboard, select the UICollectionView and turn the header section on.

section header swift

Above the custom cell, the header space will appear, select it and set the identifier name to headersection.

Turn now back to the ViewController.swift class.

Inside the viewForSupplementaryElementOfKind function you can set the custom cell  content, by using the same procedure used to define the custom cell ( 1. custom cell creation - subclass of UICollectionReusableView, 2. assign the class name to the header in the main.storyboard and link variables using the assistant editor, 3. fill the content).

   func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView
        let header = collectionView.dequeueReusableSupplementaryViewOfKind(UICollectionElementKindSectionHeader, withReuseIdentifier: "headersection", forIndexPath: indexPath) as! UICollectionReusableView

        return header
    func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, referenceSizeForHeaderInSection section: Int) -> CGSize
        return CGSizeMake(CGRectGetWidth(collectionView.bounds), 50.0)

Download the example project


Leave a comment


- 12 October 2016 at 18:06
minimumInteritemSpacing brought me here, well, with the help of Google. thanks for the tutorial
- 26 March 2016 at 01:32
nice one ! very useful