Search code examples
iosswiftuipickerviewvar

Property for picker data won't retain result of for loop


I'm new to Swift and am implementing my first UIPickerView. It works fine if I set the pickerData directly in viewDidLoad like pickerData = ["item1", "item2"]. But I need to construct the picker items from a Firebase database.

I am able to construct the picker items just fine using a method that pulls the data from the database and creates a list. Then I take that list and construct my picker items. I can print the array and I see that the array is constructed properly.

But when the array is done, it apparently either reverts to empty again and my pickerview is empty, or my pickerview got set up before the array was completed and so it is empty.

I tried using Dispatch.main.async in several places - including the completion statement in my data retrieval function, around the building of the pickerData, etc. I also tried putting the entire code for the data retrieval and the construction of the pickerData array into viewDidLoad, but it's always the same. pickerData does not keep the array I constructed for it, and the pickerView is empty.

Here's my code (written in Xcode 10, Swift 4.2), from viewDidLoad:

func viewDidLoad() {
    // Set up the pickerview
    ToyService.getToyList(kid: self.kid!) { (toyList) in
        self.pickerData.removeAll()

        // Go through each toy item and create a picker item from it

        for item in toyList {
            // Set up a formatter to work with the price as a string
            let formatter = NumberFormatter()
            formatter.numberStyle = .decimal
            formatter.minimumFractionDigits = 2
            formatter.maximumFractionDigits = 2

            let price = formatter.string(from: item.price!)
            let pickerItem:String = item.title! + " " + "($" + price! + ")"

            self.pickerData.append(pickerItem)

            print(self.pickerData)
        }

        print("here's the pickerdata: \(self.pickerData)")
    }

    print("here's the pickerdata again: \(self.pickerData)")
} // end of viewDidLoad

The output of the print statements is as follows (notice the last print statement prints first, and it prints an empty array!):

here's the pickerdata again: []

["doll ($0.75)"]

["doll ($0.75)", "bear ($0.75)"]

["doll ($0.75)", "bear ($0.75)", "truck ($0.75)"]

["doll ($0.75)", "bear ($0.75)", "truck ($0.75)", "blocks ($0.75)"]

here's the pickerdata: ["doll ($0.75)", "bear ($0.75)", "truck ($0.75)", "blocks ($0.75)"]


Solution

  • You need to reload the pickerView inside the completion as it's asynchronous

    for item in toyList {   
      // ......
      self.pickerData.append(pickerItem)
      print(self.pickerData)
    }
    self.pickerView.reloadAllComponents()