我正在实现“按需搜索”功能,但是在动态更新UITableView中的行数时遇到问题。我使用UISearchBar并在用户键入三个字母后触发搜索。
我通过API来查询搜索结果,该API异步获取数据。这就是我获得结果并更新数据源数组的方式
if let text = searchBar.text {
if text.count >= minSearchStartCriteria {
let tableX:CGFloat = 0
let tableY:CGFloat = searchBar.frame.maxY
let tableWidth:CGFloat = view.frame.width
var tableHeight:CGFloat = 0
// remove the tap recognizer so that the tap on the uitableview
// can be captured
if let tapRecognizer = tapRecognizer,
let recognizers = view.gestureRecognizers {
if recognizers.count > 0 {
view.removeGestureRecognizer(tapRecognizer)
}
}
// create the UITableView
if searchResultsTable == nil {
searchResultsTable = UITableView(frame: CGRect(x: tableX, y: tableY , width: tableWidth, height: tableHeight))
if let searchResultsTable = searchResultsTable {
searchResultsTable.delegate = self
searchResultsTable.dataSource = self
searchResultsTable.register(SearchResultTableViewCell.self, forCellReuseIdentifier: "searchResultTableCell")
view.addSubview(searchResultsTable)
}
}
// update the search results
if let p = onlineSearchPresenter {
p.getSearchResults(request: text) { (results) in
self.searchResults = results
}
tableHeight = CGFloat(searchResults.count * 44)
searchResultsTable?.frame = CGRect(x: tableX, y: tableY, width: tableWidth, height: tableHeight)
searchResultsTable?.reloadData()
}
} else {
// If there is less than "minSearchStartCriteria" letters, remove the table view
searchResults.removeAll()
searchResultsTable?.removeFromSuperview()
searchResultsTable = nil
}
}
如果我键入“ abcd”,搜索将返回10个结果,因此,我的UITableView被创建为具有10行。这里没有问题。然后,如果我继续添加字母并缩小搜索范围,则返回的结果数更少,仅说4。从调试器中检查后,它显示了searchResults
数组中正确的结果数,但是{ {1}}仍然尝试从索引4中获取结果,该结果超出了其中只有四个项目的数组的范围。
看来我需要让UITableView知道数据源数组已更新,以便它可以更新其索引。我怀疑问题出在更新结果数组的异步性质之内,但无法确定确切的问题是什么。
我如何获得这项工作?
谢谢
答案 0 :(得分:2)
如果您认为问题是由于“更新结果数组的异步特性”引起的,则应使用反跳功能。
使用反跳功能可以通过在执行之前等待一定时间来限制函数启动的频率。
https://gist.github.com/DoubleREW/567f5e67262f1de781f4f9164235d4e9
https://bradfol.com/how-can-i-debounce-a-method-call-in-swift-4/