Swift/iOS : UIPicker display is not refreshed until tapped after changing the datasource programmatically

蹲街弑〆低调 提交于 2020-01-17 07:00:17

问题


In my app, I have a picker that's filled with data from my server after a POST request.

It has one element initially (used as a label), and when the POST request is filled the datasource get changed and I call picker.reloadAllComponents() to refresh it.

When this run, nothing appears to happen on screen, the picker doesn't change. But once tapped, the new data instantly appear and it works correctly. Seems like the data source change works correctly but the display doesn't change until refreshed.

Is there a way to refresh it, or a different method to change the datasource

Here's the relevant code :

class MyController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {

@IBOutlet weak var dossiers_picker: UIPickerView!
var pickerData: [Dossier] = [Dossier(nom: "Dossier", id: 0)]
// Dossier is just a tuple class with 2 attributes

override func viewDidLoad() {
    super.viewDidLoad()
    self.dossiers_picker.delegate = self
    self.dossiers_picker.dataSource = self
    getDossiers()
}

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 1
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return pickerData.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    return pickerData[row].nom
}

func getDossiers() {
    ... // Cut the code where I call the server to get the data, etc ...
    let task = session.dataTask(with: request) { data, response, error in
        guard let data = data, error == nil else {
                // check for fundamental networking error
                print("error=\(String(describing: error))")
                return
            }
        ... // get the data and turn it into an array of Dossier classes in var dossiers
        self.pickerData = dossiers
        dossiers_picker.reloadAllComponents()
    }
    task.resume()
}
}

回答1:


Figured it out when adding the asynchronous tag to the question... good old rubber duck debugging.

As said by @rmaddy, all UI updates must be done on the main thread.

In this case, replace

dossiers_picker.reloadAllComponents()

with

DispatchQueue.main.async {
    self.dossiers_picker.reloadAllComponents()
}


来源:https://stackoverflow.com/questions/45221065/swift-ios-uipicker-display-is-not-refreshed-until-tapped-after-changing-the-da

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!