使 TableView 显示基于 PickerView 中当前选择的值?

Making a TableView show values based on current selection in PickerView?

我正在尝试制作一个显示 PickerView 和 TableView 的 iOS 应用程序。 PickerView 包含 50 U.S。状态,并且 TableView 应该根据国家气象局提供的 XML 显示所选状态的当前天气警报。 XML 到 XML 对于加利福尼亚等是 https://alerts.weather.gov/cap/fl.php?x=0 for Florida, https://alerts.weather.gov/cap/ca.php?x=0。换句话说,每个州的 XML 的 URL 因两个字母的州而异缩写。

到目前为止,我已经让应用程序在 PickerView 中正确显示所有 50 个州,并且当每个州都被选中时,该州的天气警报确实会出现在 TableView 中。但是,一旦 TableView 填充了天气警报,它们就永远不会消失。我希望 TableView 显示 PickerView 中当前所选状态的警报。截至目前,每个州的天气警报不断添加到 TableView 中。此外,如果我回到我之前选择的状态,天气警报将作为副本再次添加到 TableView 的末尾。我不确定如何正确填充 TableView,以便它一次只显示每个单独状态的警报。谁能帮帮我?

这是我的代码:

class ViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource, UITableViewDataSource, UITableViewDelegate, XMLParserDelegate {

    @IBOutlet var statePicker: UIPickerView!
    @IBOutlet var alertsTable: UITableView!


    var titleFound:Bool = false
    var descFound:Bool = false
    var alerts:[String] = []
    var exps:[String] = []
    var abbv:String = ""
    var parser = XMLParser()
    var states = ["Alabama", "Alaska", "Arizona", "Arkansas", "California", "Colorado", "Connecticut", "Delaware", "Florida", "Georgia", "Hawaii", "Idaho", "Illinois", "Indiana", "Iowa", "Kansas", "Kentucky", "Louisiana", "Maine", "Maryland", "Massachusetts", "Michigan", "Minnesota", "Mississippi", "Missouri", "Montana", "Nebraska", "Nevada", "New Hampshire", "New Jersey", "New Mexico", "New York", "North Carolina", "North Dakota", "Ohio", "Oklahoma", "Oregon", "Pennsylvania", "Rhode Island", "South Carolina", "South Dakota", "Tennessee", "Texas", "Utah", "Vermont", "Virginia", "Washington", "West Virginia", "Wisconsin", "Wyoming"]
    var abbvsList = ["al", "ak", "az", "ar", "ca", "co", "ct", "de", "fl", "ga", "hi", "id", "il", "in", "io", "ks", "ky", "la", "me", "md", "ma", "mi", "mn", "ms", "mo", "mt", "ne", "nv", "nh", "nj", "nm", "ny", "nc", "nd", "oh", "ok", "or", "pa", "ri", "sc", "sd", "tn", "tx", "ut", "vt", "va", "wa", "wv", "wi", "wy"]

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

    func pickerView(_ pickerView:UIPickerView, titleForRow row: Int, forComponent component: Int)->String?
    {
        return states[row]
    }

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

    func pickerView(_ pickerView:UIPickerView, didSelectRow row:Int, inComponent component:Int)
    {
        var currentState = abbvsList[statePicker.selectedRow(inComponent: 0)]
        parser = XMLParser(contentsOf:(NSURL(string:"http://alerts.weather.gov/cap/\(currentState).php?x=0") as! URL))!
        parser.delegate = self
        parser.parse()
        alertsTable.reloadData()
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        statePicker.delegate = self
        statePicker.dataSource = self
        self.alertsTable.register(UITableViewCell.self, forCellReuseIdentifier: "cell")
        alertsTable.delegate = self
        alertsTable.dataSource = self
    }

    func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
        if(elementName == "cap:event") {
            titleFound = true
        }
        if(elementName == "cap:expires") {
            descFound = true
        }
    }

    func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
        if(elementName == "cap:event") {
            titleFound = false
        }
        if(elementName == "cap:expires") {
            descFound = false
        }
    }

    func parser(_ parser: XMLParser, foundCharacters string: String) {
        if(titleFound) {
            alerts.append(string)
        }
        if(descFound) {
            exps.append(string)
        }
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return alerts.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell:UITableViewCell = UITableViewCell(style:UITableViewCellStyle.subtitle, reuseIdentifier: "cell")
        cell.textLabel!.text = alerts[indexPath.row]
        cell.detailTextLabel!.text = "Expires: "+exps[indexPath.row]
        return cell
    }

    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        //What happens when the cell is tapped`
    }
}

您不断地附加到 alertsexps 并且从不重新初始化它们。

pickerView(_:didSelectRow:inComponent) 中,在解析新输入之前将 alertsexps 设置回空:

func pickerView(_ pickerView:UIPickerView, didSelectRow row:Int, inComponent component:Int)
{
    var currentState = abbvsList[statePicker.selectedRow(inComponent: 0)]
    parser = XMLParser(contentsOf:(NSURL(string:"http://alerts.weather.gov/cap/\(currentState).php?x=0") as! URL))!

    alerts = []
    exps = []

    parser.delegate = self
    parser.parse()
    alertsTable.reloadData()
}

从代码看来,您正在通过 alerts.append(string)exps.append(string) 将 Web 请求的结果添加到 alerts & exps 数组的末尾。

而不是 append-ing,您需要先清除数组然后添加结果。