1

I have an extension that creates UIPickerView with following code

extension FirstVC {
    func createPicker() -> UIPickerView {
        let customPicker = UIPickerView(frame: CGRect(x: 0, y: 0, width: 400, height: 216))
        customPicker.backgroundColor = .white
        return customPicker
    }
}

And I have a stored property that is initialized via a closure in my view controller

private var proxyPeoplePicker: UIPickerView {
   return createPicker()
}

I also have 5 more picker view and to prevent duplication I am trying to use below above stored property but it is not working, when I try to get information inside, it always returns me its initial value. What could be the reason of it and how can I prevent code duplication with these picker views?

atalayasa
  • 3,310
  • 25
  • 42

2 Answers2

1

Computed properties act like a function. It might be useful to ensure that the result of such a property is always up to date with the current state of its dependencies.

func createPicker() -> UIPickerView {
    let customPicker = UIPickerView(frame: CGRect(x: 0, y: 0, width: 400, height: 216))
    customPicker.backgroundColor = .white
    return customPicker
}

In your case, such calculated property depends on nothing and always return a new instance of UIPickerView whenever your reference proxyPeoplePicker.

What you really want to achieve is stored property that is initialized with the view controller. It's computed only once and remains constant until you overwrite it. Here is what you need to do, to have 5 instances of pickerView to operate with:

class FirstVC : UIViewController {

    private var pickerView1: UIPickerView?
    private var pickerView2: UIPickerView?
    private var pickerView3: UIPickerView?
    private var pickerView4: UIPickerView?
    private var pickerView5: UIPickerView?

    override func viewDidLoad() {
        pickerView1 = createPicker()
        pickerView2 = createPicker()
        pickerView3 = createPicker()
        pickerView4 = createPicker()
        pickerView5 = createPicker()

        // now you can operate with your picker view

        pickerView1?.backgroundColor = .black
    }
}
  • When I try your way it gave me an error `Cannot use instance member 'createPicker' within property initializer; property initializers run before 'self' is available` – atalayasa Nov 12 '18 at 13:56
  • Thanks dude, first answer is same and written before you I am also upvoting. – atalayasa Nov 12 '18 at 14:02
0

This is because every time you try to get proxyPeoplePicker you create new instance of picker view and set it as proxyPeoplePicker. That means you don't get any informations about previous picker view because you've replaced it.

And yes, in this case you should use stored property but your property is called computed property more about properties here.

So, declare your picker views somewhere in your ViewController

private var proxyPeoplePicker: UIPickerView?
private var proxyPeoplePicker2: UIPickerView?
...

now in viewDidLoad() set picker views

proxyPeoplePicker = createPicker()
proxyPeoplePicker2 = createPicker()
...

But don't forget! If you want to get this proxyPeoplePicker instance you have to unwrap it

more about unwrapping here

Robert Dresler
  • 10,580
  • 2
  • 22
  • 40