简体   繁体   English

快速搜索栏-使用Alamofire请求更新表视图

[英]Swift search bar - updating table view with Alamofire request

I've made up some string search on my database and i return the JSON after the user pushes the 3rd character on search bar, after that I append all the results to an Array and it fills a tableview with data. 我在数据库上进行了一些字符串搜索,当用户在搜索栏上按下第三个字符后,我返回了JSON,然后将所有结果附加到数组中,并用数据填充了表格视图。

Although I'm dealing with an issue. 虽然我正在处理一个问题。 When I search lets say for mens I get the results appear on the tableview 当我搜索说mens我得到的结果出现在表格视图中

If i delete all the text and i write women, all good... but when i'm deleting some strings etc i get an error index out of range inside the tableview cellForRowAt. 如果我删除所有文本并写成女人,一切都很好...但是当我删除一些字符串等时,我在表视图cellForRowAt中得到了index out of range的错误index out of range I guess that it breaks cause the tableview doesn't have the time to get the appended array and fill the cells. 我猜想它会中断,因为tableview没有时间获取附加数组并填充单元格。

What I'm trying to find out is how can i make it work, WITHOUT setting a time delay on the query or in the reloadData() . 我试图找出的是如何在reloadData()查询或reloadData()设置时间延迟的情况下使其工作。 The reason I don't want time delay is because some user's might have a slow - old iPhone and even with 2 sec delay, it could crash. 我不希望延迟时间的原因是,某些用户的计算机可能运行缓慢-旧的iPhone,即使延迟2秒,也可能崩溃。

This is my code 这是我的代码

class SearchViewController: UIViewController, UITableViewDelegate, UITableViewDataSource, UISearchBarDelegate, UISearchControllerDelegate{

@IBOutlet weak var searchResultTable: UITableView!
    let searchController = UISearchController(searchResultsController: nil)

    var filteredData = [Products]()

override func viewDidLoad() {
        super.viewDidLoad()


        self.navigationController?.isNavigationBarHidden = true
        searchController.searchResultsUpdater = self
        searchController.dimsBackgroundDuringPresentation = false
        definesPresentationContext = true
        searchResultTable.tableHeaderView = searchController.searchBar

        searchController.searchBar.delegate = self

    }


func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
        searchBar.resignFirstResponder()
    }


    func getSearch(completed: @escaping DownloadComplete, searchString: String) {
        if filteredData.isEmpty == false {
            filteredData.removeAll()
        }
        let parameters: Parameters = [
            "action" : "search",
            "subaction" : "get",
            "product_name"  : searchString,
            "limit" : "0,30"
        ]


        Alamofire.request(baseurl, method: .get, parameters: parameters).responseJSON { (responseData) -> Void in
            if((responseData.result.value) != nil) {
                let result = responseData.result

                if let dict = result.value as? Dictionary<String, AnyObject>{
                    if let list = dict["product_details"] as? [Dictionary<String, AnyObject>] {

                        for obj in list {
                            let manPerfumes = Products(productDict: obj)
                            self.filteredData.append(manPerfumes)
                        }


                    }
                }
                completed()
            }
        }
    }


func numberOfSections(in tableView: UITableView) -> Int {

        return 1

    }
    func tableView(_ tableView: UITableView,
                   heightForRowAt indexPath: IndexPath) -> CGFloat {
        return 170
    }

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

        return filteredData.count
    }

    func tableView(_ tableView: UITableView,
                   cellForRowAt indexPath: IndexPath) -> UITableViewCell {

            let cell:iPhoneTableViewCell = tableView.dequeueReusableCell(withIdentifier: "iPhoneTableCell", for: indexPath) as! iPhoneTableViewCell

            let prods = self.filteredData[indexPath.row] //HERE I GET THE ERROR
            cell.configureCell(products: prods)

            return cell

    }

}

extension SearchViewController: UISearchResultsUpdating {

    func updateSearchResults(for searchController: UISearchController) {

        if (searchController.searchBar.text?.characters.count)! >= 3 {
                    self.getSearch(completed: {
                    self.searchResultTable.reloadData()

                    self.searchResultTable.setContentOffset(CGPoint.zero, animated: true)
                }, searchString: searchController.searchBar.text!)
        } else {
            self.searchResultTable.reloadData()
        }


    }
}

It looks like you are changing the state of filteredData while the tableView does reloadData . 看起来您在更改tableView确实是reloadData同时filteredData的状态。 If numberOfRowsForSection returns 3, and then the user hits the delete key for example, the array size will become 0. That may be why cellForRow throws an exception when requesting indices 0,1 or 2. 如果numberOfRowsForSection返回3,然后用户按下了Delete键,则数组大小将变为0。这可能就是为什么cellForRow在请求索引0、1或2时引发异常的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM