Tutorial: A Simple iOS Collection View in Swift

Introduction
A collection view is a great way to present view elements in a grid-like arrangement. The precise layout of visual elements is definable through subclassing a collection view. Collection views are packaged with a data source facility that makes it possible for an app to generate data-driven views (collection view cells). In this tutorial we will create a subclass of a UICollectionView and write a random color generating function to supply our collection view data for its cells.



For more information on collection views click here.

Creating the Project
1a. Open Xcode. From the welcome screen, see figure 1, select Create a new Xcode project from the menu.
Figure 1

2a. To the the left of the project template menu, locate the category item iOS > Application within the sidebar and select it; locate the Single View Application, select it then click on the button labeled Next. See figure 2.
Figure 2

3a. In the project options menu you are prompted to enter several option. Fill out the first three options. For the language drop down menu select Swift. For the devices dropdown menu select iPad since we will be building an iPad only application. See figure 3.
Figure 3

4a. On the last menu option you are asked to select a location for you project and given the option to place your project under source control. Select where you want your project to live and if you are familiar with Git for source control and would like to use it, then make sure that the check box next to the label Source Control is selected. Click on the button labeled Create to continue. You should now see Xcode open as shown in figure 4.
Figure 4


Collection View Controller Subclass
1b. In the Project Navigator pane, located to the left of Xcode, hover your mouse pointer over the top most grouping folder (colored orange/yellow) and right click your mouse. A drop down menu, as shown in figure 5, should appear; select New File... to create a new file. A file menu template will appear.
Figure 5

2b. From the file menu template, see figure 6, choose iOS > Source, Cocoa Touch Class and click on the button labeled Next.
Figure 6

3b. On the next menu, see figure 7, you are prompted to enter options for your new file. From the drop down menu labeled Subclass of choose or type in, UICollectionViewController. In the text field, labeled Class, ensure that it reads AGWCollectionViewController. (Coding convention dictates that we prefix our custom class names with at least three letters that represent us or our organization. This technique helps to mitigate naming collisions with existing class names. In our case AGW stands for aGupieWare.) From the drop down menu labeled Language ensure that Swift is selected. Also ensure that the box labeled Also create XIB file is unchecked; since we will be using a Storyboard to define the appearance of our collection view we won't be needing individual XIB files. Now click on the button labeled Next to generate our collection view controller subclass.
Figure 7

4b. From the Project Navigator pane, select our newly generated class. You should now see the contents of this class in the Editor pane as shown in figure 8. The Editor pane is where we will be doing all of our coding. You will notice that there is code already written for us. This is the boilerplate code that is provided for us when we create a subclass of a collection view controller. More on this controller later.
Figure 8

Main Storyboard & AGWCollectionViewController
5b. From the Project Navigator pane, select the Main.storyboard item. A Storyboard is a canvas of sorts where we may layout various view controllers and define the order/hierarchy in which they are presented to the end user. In the Editor pane you should see a visual representation of the Root View Controller. A root view controller is the entry point of any iOS application. You know if a view controller is the root when it is annotated with an arrow as shown in figure 9.
Figure 9

6b. The current view controller within our storyboard is to generic for our needs. Xcode's Object Library pane provides us with various type of view controllers for us to use. (To view the Utilities pane ensure that the top right most segmented button in Xcode is selected). From the Utilities pane select the sub menu item labeled Show the Object Library. It's located in the lower portion of the Utilities pane. The exposed Object Library pane includes a search bar; use it to locate a Collection View Controller, and drag-and-drop the item into our storyboard Editor pane as shown in figure 10.
Figure 10

7b. We now make our Collection View Controller the root view controller so that when our app starts, it presents this controller instead. To do this, simply move the arrow from the Default View Controller to our recently added Collection View Controller by clicking and dragging it over as depicted by figure 11. In order to keep our storyboard tidy we should delete the Default View Controller that was provided to us upon creation of our storyboard; select it and press the delete key. An item in a storyboard is said to be selected when it is annotated with a blue border.
Figure 11

8b. Select the root collection view controller within our storyboard. Open the Utilities pane. Within the Utilities pane select the Identity Inspector sub menu item. In the Utilities menu section labeled Custom Class, change Class to read AGWCollectionViewController. After following these steps, your storyboard's properties should look similar to figure 12. What we have done is bind/associate the visual representation of a Collection View Controller to our custom AGWCollectionViewController subclass.
Figure 12


Build and Run App
1c. Before we can build and run our app we need to select an App Target and a Device Simulator. Any app generated via Xcode will have at least one app target along with a handful of available device simulators for us to use. Near the upper left corner of Xcode, we find a set of nested drop down menus for selecting an app target along with a device simulator for building and running our app. Figure 13 shows us how we would go about selecting AGW Collection View app target along with an iPad Air device simulator. Go ahead make the selection in Xcode. To run the app, click on the button with the Play icon. If things went as planed, our device simulator should have loaded with our app; you should see a blank screen since we haven't coded any logic to display visual elements yet.

Figure 13



Populating Collection View with Cells
1d. If up to this point you have followed our steps to the letter, then our collection view controller should already be setup with a generic and reusable Collection View Cell ready to be used by our code that we will shortly be writing.

2d. From the Project Navigator pane select our AGWCollectionViewController class so that its content is made visible in the Editor pane as shown in figure 8.

3d. In the Editor pane, locate the function named viewDidLoad() and add these lines of code to it:
// "seed" our random number generator //
srand48(Int(arc4random()));
The code above "seeds" our random number generator so that on successive app launches we don't get the same stream of random numbers as previous app launches. We will be using a random number generator to randomly pick background colors for our collection view cells. For more information on the random number generator that we will be using click here.
The viewDidLoad() function should now look similar to this code snippet:
override func viewDidLoad() {
    super.viewDidLoad()

    // Uncomment the following line to preserve selection between 
    //   presentations
    // self.clearsSelectionOnViewWillAppear = false

    // Register cell classes
    self.collectionView!.registerClass(UICollectionViewCell.self, 
      forCellWithReuseIdentifier: reuseIdentifier)

    // Do any additional setup after loading the view.

    // "seed" our random number generator //
    srand48(Int(arc4random()));
}

4d. Just like viewDidLoad() is a defined function, we will define our own function that provides us with a random color. Using the Editor, insert the following function within our AGWCollectionViewController class:
func randomColor() -> UIColor {

    var randomRed:CGFloat = 0.0
    var randomGreen:CGFloat = 0.0
    var randomBlue:CGFloat = 0.0
    let nonRandomAlpha:CGFloat = 1.0

    // reject colors that are too dark -- colors //  
    // are rejected 0.35/3 = %11.6 of the time   //
    while ( randomRed + randomGreen + randomBlue < 0.35) {

        // for each color channel we generate a random number //

        randomRed = CGFloat(drand48())
        randomGreen = CGFloat(drand48())
        randomBlue = CGFloat(drand48())
    }

    // build and return a color object   //
    // with the generated random numbers //
    return UIColor(red: randomRed, 
      green: randomGreen, 
      blue: randomBlue, 
      alpha: nonRandomAlpha)

}

5d. Locate the function collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell and add to it the following line of code:
cell.contentView.backgroundColor = randomColor()
so that this function's content looks like this:
override func collectionView(collectionView: UICollectionView, 
  cellForItemAtIndexPath indexPath: NSIndexPath) -> 
  UICollectionViewCell {

    let cell = collectionView.dequeueReusableCellWithReuseIdentifier(
      reuseIdentifier, forIndexPath: indexPath) as! 
      UICollectionViewCell
    
    // Configure the cell with random color //
    cell.contentView.backgroundColor = randomColor()

    return cell
}

6d. We now specify the number of cells that we want to display to the user. Ensure that the following two functions look like this:
override func numberOfSectionsInCollectionView(collectionView: 
  UICollectionView) -> Int {

    // Return the number of sections
    return 1
}

override func collectionView(collectionView: UICollectionView, 
  numberOfItemsInSection section: Int) -> Int {
    
    // Return the number of items in the section
    return 2000
}
Data Source Functions
1e. Notice that some of the functions are prefixed with the keyword override. Since we implicitly stated that the AGWCollectionViewController class will act as the Data Source for our collection view, our collection view will expect these functions to be implemented/defined and that they return proper values. This implicit connection between our Collection View and Collection View Controller acting as the Data Source was made within our storyboard when we explicitly said that the Storyboard item is of AGWCollectionViewController type, see step 8b.

Final Run
Follow the steps in 1c to setup and run our application. Your collection view app should look similar to figure 14.
Figure 14

This project can be found on GitHub.

We hope you enjoyed this tutorial. As always, comments, questions, suggestions and critique are welcome below.

No comments:

Post a Comment