搜索中的TableView数据未正确更新

时间:2018-08-22 15:07:51

标签: ios swift uitableview alamofire

我用Swift制作了一个TableView,在其中显示了UiTextField中填充的查询的搜索结果。

let cellReuseIdentifier = "cell"

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell:SearchCell = self.tableView.dequeueReusableCell(withIdentifier:cellReuseIdentifier) as! SearchCell
    cell.objectName.text = self.search_results_list[indexPath.section]
    return cell
}

值更改事件中,我触发了搜索操作:

 @IBAction func searchInputChanged(_ sender: Any) {
    self.search_results_list = []
    let search = self.searchField.text
    let parameters: Parameters = ["api_token": token, "search": search!+" "]
    let URL = "https://myweb.app/api/search"
    Alamofire.request(URL, parameters: parameters).responseArray { (response: DataResponse<[SearchResponse]>) in
        let searchResultsArray = response.result.value
        if let searchResultsArray = searchResultsArray {
            for searchResult in searchResultsArray {
                self.search_results_list.append(searchResult.description!)
            }
        }
        // Then I reloeadData of the TableView
        self.tableView.reloadData()
    }
}

还有NumberOfSections方法:

func numberOfSections(in tableView: UITableView) -> Int {
        return self.search_results_list.count
    }
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 1
    }

它确实可以工作,但是当我快速填写表格时,Array具有正确的顺序,但是TableView具有不同的顺序。当我检查数组时,我看到顺序是正确的,但是TableView显示了一个不同的顺序。当我等待一秒钟并在末尾添加一个空格时,TableView确实显示了正确的顺序。 当我逐个字母添加字母并在每个字母重新加载tableview之后等待时,输出是正确的

我想念什么?

1 个答案:

答案 0 :(得分:1)

就像他们在评论中说的那样。可能是因为异步调用在不同的时间返回。与结果结果较少(较新的电话)的人相比,结果更多结果(较早的电话)的人可能会更快。因此,您要做的是使与您的当前搜索文本不匹配不匹配的每个API响应无效。

@IBAction func searchInputChanged(_ sender: Any) {
    self.search_results_list = []
    let search = self.searchField.text
    let parameters: Parameters = ["api_token": token, "search": search!+" "]
    let URL = "https://myweb.app/api/search"
    Alamofire.request(URL, parameters: parameters).responseArray { (response: DataResponse<[SearchResponse]>) in
        if search == self.searchTextField.text {             // Compare search text with current text in searchTextField.
            let searchResultsArray = response.result.value
            if let searchResultsArray = searchResultsArray {
                for searchResult in searchResultsArray {
                    self.search_results_list.append(searchResult.description!)
                }
            }
            DispatchQueue.main.async {
                self.tableView.reloadData()
            }
        }
    }
}

重要的优化提示

您可以将API调用包装在计时器中,以便仅在用户停止在文本字段中输入字符时才单击。这有助于避免不必要的API调用。您可以通过使用Timer进行网络调用来实现。在textDidChange中启动计时器,如果在短时间内(0.5s或您认为最佳的状态)再次调用该委托,则使该计时器无效。