Swift 1.2 - 为什么我的 UIPickerView 没有显示我的数据?

Swift 1.2 - Why isn't my UIPickerView displaying my data?

我有一个 UIPickerView,我加载了从 MySQL 数据库下载的数据。数据下载并填充一个数组,然后我通过委托方法将该数组用作我的 pickerView 的数据源。

我的问题是,一切正常,除了 pickerView 在填充数组后的 20 秒内没有明显填充。我已经尝试了 运行ning 各种 self.view.LayoutIfNeeded() 之类的,并且有很多 pickerView.reloadAllComponents() 但它仍然拒绝加载可见。但是,如果用户点击 pickerView,或更改它的值(即使它明显是空的),数据会突然出现。我尝试以编程方式选择每一行以尝试强制显示它,但这没有用。

这是我下载数​​据的代码(在 viewDidLoad 上 运行):

func RetreiveStaff() {
    SetProgramMode()

    self.aUsers = [User]()
    self.pkvUser.reloadAllComponents()

    if self.booCurrentDataVersion == true {

        var url:NSURL = NSURL(string: "http://www.website.com.au/retrievestaff.php")!
        let task:NSURLSessionDataTask = NSURLSession.sharedSession().dataTaskWithURL(url, completionHandler: { (data:NSData!, response:NSURLResponse!, error:NSError!) -> Void in
            if error == nil {
                let dataArray:[AnyObject] = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil) as! [AnyObject]
                for data in dataArray {
                    let dictionary:[String:String] = data as! [String:String]
                    if dictionary["StaffID"] != nil {

                        var newUser:User = User()
                        newUser.name = dictionary["LastName"]! + ", " + dictionary["FirstName"]!
                        newUser.id = dictionary["StaffID"]!.toInt()!
                        self.aUsers.append(newUser)

                        self.pkvUser.reloadAllComponents()
                        self.booDownloadedUsers = true
                    } else {
                        let actionSheet:UIAlertController = UIAlertController(title: "No Users Downloaded", message: "Please ensure a user has been entered in Access and then restart the app.", preferredStyle: UIAlertControllerStyle.Alert)
                        let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {
                            (alertAction:UIAlertAction!) in
                        })
                        actionSheet.addAction(firstAlertAction)
                        self.presentViewController(actionSheet, animated: true, completion: nil)
                    }
                    self.pkvUser.reloadAllComponents()
                }
                println("\(self.aUsers.count) Staff Downloaded")
                self.pkvUser.reloadAllComponents()
                self.view.setNeedsLayout()
            } else {
                let actionSheet:UIAlertController = UIAlertController(title: "Connection Error", message: "\(strAppName) was unable to load data.  Check you are connected to the internet and restart the app.", preferredStyle: UIAlertControllerStyle.Alert)
                let firstAlertAction:UIAlertAction = UIAlertAction(title: "OK", style: UIAlertActionStyle.Default, handler: {
                    (alertAction:UIAlertAction!) in
                })
                actionSheet.addAction(firstAlertAction)
                self.presentViewController(actionSheet, animated: true, completion: nil)
            }
        })

        task.resume()

    }
}

这是我的 pickerView 委托方法:

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
    return self.aUsers[row].name
}

func pickerView(pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    if count(self.aUsers) > 0 {
        strSelectedUser = self.aUsers[row]
    }
}

func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return self.aUsers.count
}

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

其中 aUsers 是我创建的自定义 'User' 对象数组。

我需要做什么才能查看 refresh/reload/display 数据,因为我知道数据就在那里。我也明白我正在异步下载它,这可能会导致这样的问题,但数据几乎是立即下载的,我不明白为什么视图跟不上。

提前致谢。

这可能是因为您总是必须在主线程中更新 UI,所以一旦您加载了数据(我认为是在 for 循环之后),当您想要调用 reloadAllComponents() 时,您必须像下面那样做。

let priority = DISPATCH_QUEUE_PRIORITY_DEFAULT

dispatch_async(dispatch_get_global_queue(priority, 0)) {
    dispatch_async(dispatch_get_main_queue()) {
        self.pkvUser.reloadAllComponents()
    }
}