Swift/iOS : 以编程方式更改数据源后,直到点击 UIPicker 显示才会刷新
Swift/iOS : UIPicker display is not refreshed until tapped after changing the datasource programmatically
在我的应用程序中,我有一个选择器,它在 POST 请求后填充了来自我的服务器的数据。
它最初只有一个元素(用作标签),当 POST 请求被填充时,数据源发生变化,我调用 picker.reloadAllComponents() 来刷新它。
当这个 运行 时,屏幕上似乎没有任何反应,选择器没有改变。但是一旦点击,新数据就会立即出现并且可以正常工作。似乎数据源更改工作正常,但显示在刷新之前不会更改。
有没有刷新它的方法,或者改变数据源的不同方法
相关代码如下:
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()
}
}
在问题中添加异步标记时弄明白了...老橡皮鸭调试。
正如@rmaddy 所说,所有 UI 更新必须在主线程上完成。
在这种情况下,替换
dossiers_picker.reloadAllComponents()
和
DispatchQueue.main.async {
self.dossiers_picker.reloadAllComponents()
}
在我的应用程序中,我有一个选择器,它在 POST 请求后填充了来自我的服务器的数据。
它最初只有一个元素(用作标签),当 POST 请求被填充时,数据源发生变化,我调用 picker.reloadAllComponents() 来刷新它。
当这个 运行 时,屏幕上似乎没有任何反应,选择器没有改变。但是一旦点击,新数据就会立即出现并且可以正常工作。似乎数据源更改工作正常,但显示在刷新之前不会更改。
有没有刷新它的方法,或者改变数据源的不同方法
相关代码如下:
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()
}
}
在问题中添加异步标记时弄明白了...老橡皮鸭调试。
正如@rmaddy 所说,所有 UI 更新必须在主线程上完成。
在这种情况下,替换
dossiers_picker.reloadAllComponents()
和
DispatchQueue.main.async {
self.dossiers_picker.reloadAllComponents()
}