UIPickerView – Getting Started


  • Share on Pinterest

There are some things you will most likely use a lot, it seems that one of those is the UIPickerView. This is pretty straight forward to start using, so let's take a look.

In this tutorial I'm going to show you how to create a UIPickerView control and power it up with some simple data, this is just a place to start from, as always there is a long journey ahead. Another plus is that if you have not been exposed to delegation and protocols then you will be now 🙂

First create a new single view project as that is all we need for this example. Then find the Picker View control in the object library and drag an instance to the storyboard. You will also want to create an @IBOutlet for the picker, by now I'm assuming I do not need to cover how to do that, if not then see any of my previous Swift posts.

01 - Starting Storyboard with Picker View.

I feel it is worth pointing out that if you run the application before configuring the picker view then you will see nothing on the screen, go ahead and try it if you don't believe me!

From here on out we will be working in the ViewController and doing everything in code, so either open up the assistant view or just open the ViewController.swift file. There are a couple of steps we have to undertake to get things started.

  1. Make our ViewController the delegate for the picker view and it's data source.
  2. Create some data to use in the picker.

We can quickly create a basic data source to power the control by adding a simple array, add the following just after the opening class statement

let myDataArray = ["Item 1", "Item 2", "Item 3"]

So let's start with making our ViewController the delegate, if you are not familiar with delegation it actually sounds a lot more complicated and scary than it really is, essentially we are saying our ViewController is responsible for the picker and has the answers to questions it will ask. To make this happen we simply alter the opening class line of code to say that not only do we extend UIViewController but we also use UIPickerViewDataSource and UIPickerViewDelegate.

class ViewController: UIViewController,
                          UIPickerViewDataSource,
                          UIPickerViewDelegate

At this point you may well see errors start to appear saying something like ‘Type ViewController' does not conform to protocol ‘UIPickerViewDataSource' in the code window, this is not surprising! We just told Xcode that our file is responsible for handling the Picker View and therefore it expects us to take care of answering some questions.

Let's stop for a second and briefly talk about what that all means. When you say you are going to take care of something then naturally you need to before the compiler with be happy, this is where we start using the official documentation to our advantage since it will tell us what protocols we need to satisfy. As you start doing this more often you will get used to it, essentially there are certain protocols we MUST now provide in our View Controller and there are plenty more that are optional depending on what you are acting as a delegate for. The documentation from Apple can help answers those questions for us by telling us what is required and what else is available should we need it. One way to get to the information is to click on UIPickerViewDataSource or UIPickerViewDelegate and use the quick help panel found to the right in Xcode if you happen to have it open, in there towards the bottom is Reference with a link you can click to open the documentation up. Or alternatively you can search the documentation using a method of your choice. Let's do it with UIPickerViewDataSource first.

03 - Documentation — UIPickerViewDataSource Protocol Reference

Notice that it tells us there are two Required protocols we need to take care of

- numberOfComponentsInPickerView
- pickerView:numberOfRowsInComponent

Let's get UIPickerViewDelegate information as well while we are at it. Do the same thing and you'll notice there are some starting

- pickerView

04 - Documentation — UIPickerViewDelegate Protocol Reference

(This ends the quick overview of finding protocol requirements) OK we had to get all that out the way some time, now back to the code since we know what we need to implement (Xcode will also remind you by complaining until you satisfy the requirements).

In our View Controller we now need to tell our picker control that we are acting as it's delegate and it's data source, to do that we add some code to our viewDidLoad() method.

// Note that my outlet for the control is named myPickerView

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    myPickerView!.dataSource = self
    myPickerView!.delegate = self
}

Now we need to start adding each of the protocols we MUST satisfy so go ahead and add the following after viewDidLoad()

func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
        if pickerView == myPickerView {
            return 1
        }
        return 0
    }

We are hardcoding the return value of 1 since we know there is only one component (selection list) in our view based on the data source we created. Also notice we are checking which picker view is calling the code this is because you could have more than one instance and want to be sure the right code executes for the right instance.

Now add the following

func pickerView(pickerView: UIPickerView,
                    numberOfRowsInComponent component: Int) -> Int {
        if pickerView == myPickerView {
            return myDataArray.count
        }
        return 0
    }

We take advantage of the count method to return the total count of items in our array and say that is the number of rows to be displayed.

Finally add

func pickerView(pickerView: UIPickerView,
                    titleForRow row: Int,
                    forComponent component: Int) -> String! {
        return myDataArray[row]
    }

This is called every time a new item is created in the component, we get the label to display from the row number and access that item via the array index, the value in the array at that position is is returned for display on the control.

The entire code in the ViewController.swift file should look something like

//
    //  ViewController.swift
    //  PickerSample
    //
    //  Created by Peter Witham on 1/22/15.
    //  Copyright (c) 2015 Peter Witham. All rights reserved.
    //
    
    import UIKit
    
    class ViewController: UIViewController,
                          UIPickerViewDataSource,
                          UIPickerViewDelegate {
    
        @IBOutlet weak var myPickerView: UIPickerView!
        let myDataArray = ["Item 1", "Item 2", "Item 3"]
    
        override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            myPickerView!.dataSource = self
            myPickerView!.delegate = self
        }
    
        override func didReceiveMemoryWarning() {
            super.didReceiveMemoryWarning()
            // Dispose of any resources that can be recreated.
        }
    
        func numberOfComponentsInPickerView(pickerView:UIPickerView) -> Int {
            if pickerView == myPickerView {
                return 1
            }
            return 0
        }
    
        func pickerView(pickerView: UIPickerView,
                        numberOfRowsInComponent component: Int) -> Int {
            if pickerView == myPickerView {
                return myDataArray.count
            }
            return 0
        }
    
        func pickerView(pickerView: UIPickerView,
                        titleForRow row: Int,
                        forComponent component: Int) -> String! {
            return myDataArray[row]
        }
    }

Now run the application and you should have a picker displayed showing our list of items!

05 - iOS Simulator

So there was a lot to read for just one simple(?) control, but we had to cover some important topics like delegation and protocols and this felt like the time to get an introduction out of the way.

From here your home work is to see what changes you would need to make for displaying more than one component in the control and have say two selectors. A natural progression from this would be to look at the date and time picker which has lots of components.

  • Daniel Wich
    Author
    Daniel Wich Daniel Wich

    You’re missing:
    myPickerView!.dataSource = self
    myPickerView!.delegate = self
    …in viewDidLoad in your final code example?

    • Peter Witham
      Author
      Peter Witham Peter Witham

      Thanks for the catch Daniel, I will take a look and fix it up.