【问题标题】:iOS Crash error indexPath out of bounds when searching in TableView在 TableView 中搜索时,iOS 崩溃错误 indexPath 越界
【发布时间】:2019-01-01 03:45:01
【问题描述】:

我有 2 个数组,一个是 base 包含 532 个元素,另一个是 filter 数组。我有UISearchBar,它有委托方法

func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
    self.filter(searchText: searchText)
}

private func filter(searchText: String) {
    if searchText.isEmpty {
        self.filterDelegates = self.delegates
    } else {
        self.filterDelegates = self.delegates.filter {
            $0.delegate.fullName.lowercased().contains(searchText.lowercased())
        }
    }
    self.tableView.reloadData()
}

当我滚动 tableview 并开始搜索时它崩溃了,它没有在 self.tableView.reloadData() 方法上重置 indexPath

在索引路径的 CellforRow 中登录

INDEXPATH : 23
FILTER COUNT : 396
INDEXPATH : 22
FILTER COUNT : 20


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(
            withIdentifier: DelegateTableViewCell.defaultReuseIdentifier
        ) as! DelegateTableViewCell
        print("INDEXPATH : \(indexPath.row)")
        print("FILTER COUNT : \(self.filterDelegates.count)")
        cell.item = self.filterDelegates[indexPath.row] // Index out of bound
        return cell
    }

我也使用相同的过滤器数组。行数法

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

我做错了什么?

【问题讨论】:

  • 发布UITableViewDataSource函数numberOfRows的内容
  • FILTER COUNT : 20, INDEXPATH : 22, return self.filterDelegates.count 我想这是你的问题
  • 检查索引
  • @PrashantTukadiya 是一种解决方法,可以解决真正的问题。
  • 不知道它是否会工作,但你可以把它放在开始更新和结束更新块中

标签: ios swift uitableview uisearchbar


【解决方案1】:

每次先滚动,然后更新。

private func filter(searchText: String) {

if searchText.isEmpty {
    self.filterDelegates = self.delegates
} else {
    self.filterDelegates = self.delegates.filter {
        $0.delegate.fullName.lowercased().contains(searchText.lowercased())
    }
}

UIView.animate(withDuration: 0.5, delay: 0.3, animations: {
    // animation stuff      
    self.tableView.setContentOffset( CGPoint(x: 0.0, y: 0.0), animated: false)

}, completion: { _ in
    // do stuff once animation is complete
    self.tableView.reloadData()

})

}

【讨论】:

    【解决方案2】:

    既然你说在表格视图滚动时会发生这种情况,我会像这样在搜索功能内部终止滚动:

    private func filter(searchText: String) {
        //force stop the scroll
        tableView.setContentOffset(tableView.contentOffset, animated: false) 
    
        if searchText.isEmpty {
            self.filterDelegates = self.delegates
        } else {
            self.filterDelegates = self.delegates.filter {
                $0.delegate.fullName.lowercased().contains(searchText.lowercased())
            }
        }
        self.tableView.reloadData()
    }
    

    【讨论】:

    • 索引仍将保持不变,因此在这种情况下它也会崩溃
    • 你认为还是你知道?我认为发生崩溃是因为UITableView 想要在您更改其dataSource 时正确获取下一个单元格,因为它正在滚动,如果我们停止滚动UITableView 将不需要下一个IndexPath,因此崩溃将避免......但是如果它仍然崩溃,请告诉我......
    【解决方案3】:

    我不确定,但可能是主线程问题。请尝试将self.tableView.reloadData() 放在主线程中。喜欢,

    DispatchQueue.main.async { self.tableView.reloadData() }

    【讨论】:

    • Dispatch 用于数据更新另一个线程时,这里所有进程都在主线程上。这就是为什么这永远行不通
    • 他在调用reloadData之前更新了他的数据源
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-06
    • 2015-03-22
    相关资源
    最近更新 更多