Search code examples
iosxcodeswiftuipickerviewpicker

Setting up a Picker in swift


i am trying to create a picker so that the user can select there title (mr/mrs etc) however i keep getting 2 errors

1: Type 'ViewController' does not conform to protocol 'UIPickerViewDataSource'

2: Definition conflicts with previous value

the first is in the class viewcontoller line (line 2). the second error is in the titlepicker function at the end of the code i have search online and could find anyway to fix these

import UIKit

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource //first error here
{
@IBOutlet weak var titlepicker: UIPickerView!

var titlepickerdata : [String] = [String]()
override func viewDidLoad()
{
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    //connect data
    self.titlepicker.delegate = self
    self.titlepicker.dataSource = self
    //input data into the array
    titlepickerdata = ["Mr","Ms","Mrs","Miss","Other"]
    // The number of columns of data
    func numberOfComponentsInPickerView(titlepicker: UIPickerView) -> Int
    {
        return 1
    }

    // The number of rows of data
    func pickerView(titlepicker: UIPickerView, numberOfRowsInComponent component: Int) -> Int
    {
        return titlepickerdata.count
    }

    // The data to return for the row and column that's being passed in
    func pickerView(titlepicker: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? // second error returned here
    {
        return titlepickerdata[row]
    }
}

override func didReceiveMemoryWarning()
{
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}
}

Solution

  • You have put the definitions of numberOfComponentsInPickerView, pickerView(_:numberOfRowsInComponent:), and titlepicker(_:titleForRow:forComponent:) inside the definition of didReceiveMemoryWarning. Swift supports nested functions, so this is legal syntax. However, because they are defined inside didReceiveMemoryWarning, those functions are not instance methods so they don't meet the requirements of the UIPickerViewDataSource protocol.

    It is much easier to see this sort of problem if you indent your code properly. Then those three functions are indented an extra level, showing that they are nested inside didReceiveMemoryWarning. You can fix the indentation of the entire file using the menu option Edit > Select All (default shortcut: ⌘A), and then menu option Editor > Structure > Re-Indent (default shortcut: I).

    Also, after you move the definitions outside of didReceiveMemoryWarning, you will need to rename titlepicker(_:titleForRow:forComponent:) to pickerView(_:titleForRow:forComponent:) if you want it to be used as part of the UIPickerViewDelegate protocol.

    UPDATE

    OK, now you have taken the three functions out of didReceiveMemoryWarning and put them in viewDidLoad, which is wrong for exactly the same reasons. Those functions need to be on the same level as viewDidLoad and didReceiveMemoryWarning.