Load data from json using UIPickerView

巧了我就是萌 提交于 2019-11-28 02:04:13

问题


My Current View Controller is like this

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.
}


}

I don't know how to show value to UIPickerView from my json dictionary.i don't want key to show at UIPickerView.I am now stuck at "?????" statement.

This is my output for result

[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]

Please help!!!


回答1:


If you wanted to show data to a picker view, use declare 2 arrays as properties instead.

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

Inside your viewDidLoad function

var venues = JSON(jsonData!)

let d = venues.dictionaryValue

for (k, v) in venues {
    resultKeys.append(k)
    resultValues.append(v)
}

venuePicker.dataSource = self
venuePicker.reloadAllComponents()

Then inside 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
}

This way resultKeys[pickerView.selectedRowInComponent(0)] will return the key for the selected value.




回答2:


Alamofire is totally async. It means that the block code will be executed when the data is ready. By then, the PickerView is already loaded, with an empty Array. That's the reason why the PickerView is empty. So in order to display the data we want, we need to force the PickerView to reload:

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

If you're not familliar with the concept of async programming, you can also choose to use sync way. Using this code I wrote https://github.com/skyline75489/swift-playground/blob/master/swift-playground%2FRequests.swift, we can easily send sync requests.

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

The reason why we have async is sometimes the data can be big and using sync way will cause the viewDidLoad to take forever to load. That's awful for user experience. However, if the data is small. Sync way can finish the task fast enough that users won't feel it. It's totally OK to use sync ways.



来源:https://stackoverflow.com/questions/28166944/load-data-from-json-using-uipickerview

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