3组件动态多级UIPickerView Swift

3

我刚开始学Swift编程(只是出于兴趣:)),现在正在尝试创建一个包含3个组件的UIPickerView,其中每个组件的值都基于先前选择的组件而变化。我已经接近成功了,但卡在了最后一个组件上-在我的pickerView titleForRow方法中出现致命错误:索引超出范围(当它要返回cities[selectedCity].post[row]时)。 任何建议/帮助将不胜感激!

提前感谢。

import UIKit

class Country { var name: String var cities: [City]

init(name:String, cities:[City]) {
    self.name = name
    self.cities = cities
}

这段文本是 Swift 代码,不是英语。以下是它的翻译:
类 City { 变量 名称: 字符串 变量 帖子: [字符串] }
init(name:String, posts:[String]) {
    self.name = name
    self.posts = posts
}

该文本是一个Swift语言中的类定义,其中ViewController类继承自UIViewController类,并实现了UIPickerViewDelegate和UIPickerViewDataSource协议。
@IBOutlet weak var pickerView: UIPickerView!
@IBOutlet weak var countryLbl: UILabel!

var countries = [Country]()

override func viewDidLoad() {

    pickerView.delegate = self
    pickerView.dataSource = self

    countries.append(Country(name: "UK", cities: [City(name: "London", posts: ["L01", "L02", "L03"]),City(name: "Manchester", posts: ["M01", "M02"]), City(name: "Bristol", posts: ["B01", "B02", "B03"])]))
    countries.append(Country(name: "USA", cities: [City(name: "New York", posts: ["N01"]),City(name: "Chicago", posts: ["C01", "C02"])]))
    countries.append(Country(name: "China", cities: [City(name: "Beijing", posts: ["BL01", "BL02", "BL03", "BL04"]),City(name: "Shanghai", posts: ["SM01", "SM02"]), City(name: "Shenzhen", posts: ["SB01", "SB02", "SB03"]), City(name: "Hong Kong", posts: ["SH01"])]))

    super.viewDidLoad()

}

func numberOfComponents(in pickerView: UIPickerView) -> Int {
    return 3
}

func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {

    if component == 0 {
        return countries.count
    } else if component == 1 {
        let selectedCountry = pickerView.selectedRow(inComponent: 0)
        return countries[selectedCountry].cities.count
    } else {
        let selectedCountry = pickerView.selectedRow(inComponent: 0)
        let selectedCity = pickerView.selectedRow(inComponent: 1)
        return countries[selectedCountry].cities[selectedCity].posts.count
    }
}

func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
    if component == 0 {
        return countries[row].name
    } else if component == 1{
        let selectedCountry = pickerView.selectedRow(inComponent: 0)
        return countries[selectedCountry].cities[row].name
    } else {
        let selectedCountry = pickerView.selectedRow(inComponent: 0)
        let selectedCity = pickerView.selectedRow(inComponent: 1)
        return countries[selectedCountry].cities[selectedCity].posts[row]
    }
}

func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
    pickerView.reloadComponent(0)
    pickerView.reloadComponent(1)

    let selectedCountry = pickerView.selectedRow(inComponent: 0)
    let selectedCity = pickerView.selectedRow(inComponent: 1)
    let selectedPost = pickerView.selectedRow(inComponent: 2)
    let post = countries[selectedCountry].cities[selectedCity].posts

    countryLbl.text = "The right answer was: \(post) in \(selectedCountry)"

}

}


在didSelectRow中,使用reloadAllComponents而不是仅仅重新加载1个组件。但是,在重新加载所有组件之后,帖子仍然与城市无关。因此,您需要修改对象属性。 - Jay Patel
1个回答

2
创建如下的国家和城市对象。将城市数组分配给cities。
class Country {

    var name: String
    var cities: [City]

    init(name:String, cities:[City]) {
        self.name = name
        self.cities = cities
    }
}

class City {

    var name: String
    var posts: [String]

    init(name:String, posts:[String]) {
        self.name = name
        self.posts = posts
    }
}

非常感谢JD。那非常有帮助。我已经更新了我的代码(在正文中进行编辑),但似乎仍然出现同样的错误。您有什么想法/建议吗?再次感谢! - K.K.
在didSelectRow中,使用reloadAllComponents而不是0和1。 - Jay Patel
不可能!!!那个起作用了!!JD - 你真是一个绅士和学者!这结束了数天的痛苦。非常感谢。 - K.K.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接