问题
I have these JSON output using PHP.
[
{"number":"001","name":"MIKE"},
{"number":"002","name":"JOSH"}
]
In Swift, I managed to select "name" value and display it into UIPickerView like below.
DropdownJSON.swift
import UIKit
class DropdownJSON: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITextFieldDelegate {
@IBOutlet var dropdownTxt: UITextField!
@IBOutlet var dropdownPV: UIPickerView!
@IBOutlet var numberLbl: UILabel!
@IBOutlet var nameLbl: UILabel!
var persons = [Person]()
struct Person {
var number:String
var name: String
init?(dict: [String:Any]) {
guard let number = dict["number"] as? String, let name = dict["name"] as? String else {
return nil
}
self.number = number
self.name = name
}
}
override func viewDidLoad() {
super.viewDidLoad()
getDropdownJSON()
}
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.persons.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return persons[row].name
}
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
self.numberLbl.text = self.persons[row].number
self.nameLbl.text = self.persons[row].name
self.dropdownPV.isHidden = true
self.dropdownTxt.resignFirstResponder()
}
func textFieldDidBeginEditing(_ textField: UITextField) {
if textField == self.dropdownTxt{
self.dropdownPV.isHidden = false
}
}
func getDropdownJSON() {
let url = URL(string: "http://localhost/DropdownJSON.json")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
guard let data = data, error != nil else {
print(error?.localizedDescription)
return
}
if let array = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [[String:Any]] {
self.persons = array.flatMap(Person.init)
DispatchQueue.main.async {
self.dropdownPV.reloadAllComponents()
}
}
}
task.resume()
}
}
But my goal is to display JSON output "number" into numberLbl and "name" into nameLbl in function pickerView (didSelectRow).
The reason is I want to post the numberLbl only later on. nameLbl is just to display on the screen page.
Is it possible ? Appreciate if someone can help on this matters.
UPDATE
Thanks.
回答1:
First of all you need to use URLSession.dataTask
to get response from URL
instead of NSData(contentsOf:)
. Also in Swift 3 use native URL
and Data
instead of NSURL
and NSData
.
Now the problem is you are not storing the number
value form dictionary. The simplest way to manage this situation is to create struct
and store both number
and name
value with it. After that create Array of that struct instead of Array of AnyObject
.
struct Person {
var number:String
var name: String
init?(dict: [String:Any]) {
guard let number = dict["number"] as? String, let name = dict["name"] as? String else {
return nil
}
self.number = number
self.name = name
}
}
Now declare one array of struct Person
and with your getDropdownJSON
method add data with in it.
var persons = [Person]()
func getDropdownJSON() {
let url = URL(string: "http://localhost/getDropdownJSON.json")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
guard let data = data, error == nil else {
print(error?.localizedDescription)
return
}
if let array = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [[String:Any]] {
self.persons = array.flatMap(Person.init)
DispatchQueue.main.async {
dropdownPV.reloadAllComponents()
}
}
}
task.resume()
}
Now in PickerViewDelegate
method use this array to fill its component.
func numberOfComponents(in pickerView: UIPickerView) -> Int {
return 1
}
func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
return self.persons.count
}
func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
return persons[row].name
}
Now in didSelectRow
you need to simply access array object and you will be get the number
and name
both.
func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
if row >= self.persons.count {
return
}
self.numberLbl.text = self.persons[row].number
self.nameLbl.text = self.persons[row].name
self.dropdownPV.isHidden = true
self.dropdownTxt.resignFirstResponder()
}
来源:https://stackoverflow.com/questions/42941242/how-to-display-json-into-uilabel-using-uipickerview-in-swift-3-0