swift - 输入字符时搜索栏崩溃的应用程序
问题描述
我有一个UITableView
正在填充位置的搜索栏和一个设置为该标题的搜索栏UITableView
。
每当输入某些字符或输入一定数量的字符时,应用程序就会崩溃,没有给我错误代码。
有时应用程序在输入一个字符后崩溃,可能是 2 个字符,可能是 3 个,或者可能是 4 个。崩溃背后似乎没有明显的原因。
搜索功能会正确搜索并填充过滤后的结果,但如果输入看似任意数量的字符,则无明显原因会崩溃。
我已经尝试过使用异常断点工具,但它没有为我提供任何新信息。我认为这与没有搜索结果有关。
override func viewDidLoad() {
super.viewDidLoad()
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search Locations..."
navigationItem.hidesSearchBarWhenScrolling = false
searchController.hidesNavigationBarDuringPresentation = false
locationTableView.tableHeaderView = searchController.searchBar
searchController.searchBar.sizeToFit()
searchController.searchBar.showsCancelButton = false
searchController.searchBar.barTintColor = UIColor.white
filteredData = locationList
// Sets this view controller as presenting view controller for the search interface
definesPresentationContext = true
locationList = createArray()
// Reload the table
let range = NSMakeRange(0, self.locationTableView.numberOfSections)
let sections = NSIndexSet(indexesIn: range)
self.locationTableView.reloadSections(sections as IndexSet, with: .fade)
}
func updateSearchResults(for searchController: UISearchController) {
filterContentForSearchText(searchController.searchBar.text!)
}
func searchBarIsEmpty() -> Bool {
// Returns true if the text is empty or nil
return searchController.searchBar.text?.isEmpty ?? true
}
func filterContentForSearchText(_ searchText: String) {
filteredData = locationList.filter({( locationName : Location) -> Bool in
return locationName.locationName.lowercased().contains(searchText.lowercased())
})
let range = NSMakeRange(0, self.locationTableView.numberOfSections)
let sections = NSIndexSet(indexesIn: range)
self.locationTableView.reloadSections(sections as IndexSet, with: .fade)
}
func isFiltering() -> Bool {
return searchController.isActive && !searchBarIsEmpty()
}
func locationTableView(_ locationTableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if isFiltering() {
return filteredData.count
}
return locationList.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let locationCell = locationTableView.dequeueReusableCell(withIdentifier: "locationCell", for: indexPath) as! locationCell
let location: Location
if isFiltering() {
location = filteredData[indexPath.row]
} else {
location = locationList[indexPath.row]
}
locationCell.setLocation(location: location)
return locationCell
}
预期的结果是UITableView
应该填充过滤结果。相反,如果输入太多字符(通常为 1-4 个字符),它会填充它们并崩溃。
编辑1:我通过调试错误发现:
Thread 1: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
出现在此代码块的第 2 行:
if isFiltering() {
location = filteredData[indexPath.row]
} else {
location = locationList[indexPath.row]
}
编辑 2:这是我使用的教程。
https://www.raywenderlich.com/472-uisearchcontroller-tutorial-getting-started
解决方案
似乎您期望 tableView 为您提供部分的数量......它应该由您自己的数据源驱动。
由于您没有numberOfSections
在数据源中提供 a,我假设它是 1。如果您的所有行都在 1 部分中,那么您正在执行的所有漂亮的重新加载都可以大大简化。
我建议您在https://developer.apple.com/documentation/uikit/uitableviewdatasource阅读 UITableView 数据源协议
查看您正在阅读的教程,似乎它正在使用reloadData()
强制 tableView 忽略以前的行数并使用新的行数重新加载其内容。根据您迄今为止的发现,我认为这是根本原因的一部分,表格视图错误地假设了预定的行数并试图检索不再在范围内的单元格。
推荐阅读
- python - gloud python 应用程序部署中保存的文件在哪里。?
- c# - 将 LINQ 查询结果插入 DataTable
- twitter-bootstrap - 如何更改按钮的外观
- mysql - MySQLSyntaxErrorException : 升级 MySQL 版本时出错
- python-3.x - 从键创建动态字典(给定 list_value)
- php - PHP curl 使用基本授权将表单数据发布到 REST API
- r - 使用 for 循环将 R 官员 ftext 对象添加到 fpar 对象
- python - 线程和 EventLoops 之间的 Python 共享锁
- javascript - 使用 JavaScript / jQuery 中数组中的选项递归填充选择字段
- git - 使用参数制作 git 命令