使TableView根据PickerView中的当前选择显示值?

时间:2016-10-02 23:06:07

标签: ios swift xcode uitableview uipickerview

我试图制作一个显示PickerView和TableView的iOS应用。 PickerView包含50个美国州,TableView应根据国家气象局提供的XML显示所选州的当前天气警报。 XML的URL是佛罗里达州的https://alerts.weather.gov/cap/fl.php?x=0,加利福尼亚州的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`
    }
}

2 个答案:

答案 0 :(得分:0)

您不断追加到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()
}

答案 1 :(得分:0)

从代码中看起来,您要将网络请求的结果添加到alerts&的末尾。通过expsalerts.append(string)

exps.append(string)数组

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