使用 UIPickerView 从 json 加载数据



我当前的视图控制器是这样的

import UIKit
import Alamofire
class ViewController: UIViewController , UIPickerViewDelegate, UIPickerViewDataSource{
@IBOutlet var venuePicker : UIPickerView?
var result = [String:String]()
var resultArray = [String]()
override func viewDidLoad() {
    self.venuePicker?.delegate = self
    Alamofire.request(.POST, "http://example.com/xxx/xx/xx").responseJSON() {
        (request, response, jsonData, error) in
        var venues = JSON(jsonData!)
        let d = venues.dictionaryValue
        for (k, v) in venues {
            self.result[k] = v.arrayValue[0].stringValue
        }
        self.resultArray = self.result.values.array
        self.venuePicker?.reloadAllComponents()
    }
}
func numberOfComponentsInPickerView(pickerView: UIPickerView) -> Int {
    return 1
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return resultArray.count
}
func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
    return resultArray[row]
}
override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

}

我不知道如何从我的 json 字典中向 UIPickerView 显示值。我不希望在 UIPickerView 上显示密钥。我现在停留在"?????"语句上。

这是我的结果输出

[C2517: ORIX Kobe Nyusatsu, C2510: NPS Sendai Nyusatsu, C2033: JU Gunma, C2053: KAA Kyoto, C2035: JU Ibaraki, C2077: USS Gunma, C2024: ISUZU Kobe, C2505: NAA Osaka Nyusatsu, C2529: SMAP Sapporo Nyusatsu, C2502: L-Up PKobeNyusatsu, C2005: ARAI Sendai, C2072: TAA Minami Kyushu]

请帮忙!!

如果要

向选取器视图显示数据,请改用声明 2 个数组作为属性。

var resultKeys = [String]()
var resultValues = [String]()

viewDidLoad功能内部

var venues = JSON(jsonData!)
let d = venues.dictionaryValue
for (k, v) in venues {
    resultKeys.append(k)
    resultValues.append(v)
}
venuePicker.dataSource = self
venuePicker.reloadAllComponents()

然后在里面titleForRow

func pickerView(pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String! {
    return resultValues[row]
}
func pickerView(pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
    return resultValues.count
}

这样resultKeys[pickerView.selectedRowInComponent(0)]将返回所选值的键。

Alamofire是完全异步的。这意味着块代码将在数据准备就绪时执行。到那时,PickerView 已经加载,有一个空数组。这就是 PickerView 为空的原因。因此,为了显示我们想要的数据,我们需要强制 PickerView 重新加载:

override func viewDidLoad() {
    self.venuePicker?.delegate = self // This should be outside the block, my bad.
    //...
    Alamofire.request(...) {in
        //...
        venuePicker?.reloadAllComponents() // hopefully this will work
    } 

如果你不熟悉异步编程的概念,你也可以选择使用同步方式。使用我 https://github.com/skyline75489/swift-playground/blob/master/swift-playground%2FRequests.swift 编写的这段代码,我们可以轻松地发送同步请求。

if let jsonData = Requests.get("YOUR_URL") {
     let venues = JSON(jsonData)
     //...
}

我们有异步的原因是有时数据可能很大,使用同步方式会导致viewDidLoad需要永远加载。这对用户体验来说是可怕的。但是,如果数据很小。同步方式可以足够快地完成任务,以至于用户不会感觉到它。使用同步方式是完全可以的。

最新更新