【问题标题】:Making a TableView show values based on current selection in PickerView?使 TableView 根据 PickerView 中的当前选择显示值?
【发布时间】:2016-10-02 23:06:07
【问题描述】:

我正在尝试制作一个显示 PickerView 和 TableView 的 iOS 应用程序。 PickerView 包含美国的 50 个州,而 TableView 应该根据 National Weather Service 提供的 XML 显示所选州的当前天气警报。 XML 的 URL 是 https://alerts.weather.gov/cap/fl.php?x=0 代表佛罗里达,https://alerts.weather.gov/cap/ca.php?x=0 代表加利福尼亚等等。换句话说,每个州的 XML 的 URL 会根据两个字母的州缩写而有所不同。

So far, I've gotten the app to correctly show all the 50 states in the PickerView, and when each state is selected, the weather alerts for that state do indeed appear in the 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`
    }
}

【问题讨论】:

    标签: ios swift xcode uitableview uipickerview


    【解决方案1】:

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

    【讨论】:

    • 啊,我就知道一定是这样的小事。我盯着代码看了这么久,它开始变得模糊 -_- 非常感谢!
    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2023-04-06
      • 2018-04-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-11
      • 1970-01-01
      相关资源
      最近更新 更多