首页 > 解决方案 > 输入字符时搜索栏崩溃的应用程序

问题描述

我有一个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

标签: swiftuitableviewuisearchbaruisearchcontroller

解决方案


似乎您期望 tableView 为您提供部分的数量......它应该由您自己的数据源驱动。

由于您没有numberOfSections在数据源中提供 a,我假设它是 1。如果您的所有行都在 1 部分中,那么您正在执行的所有漂亮的重新加载都可以大大简化。

我建议您在https://developer.apple.com/documentation/uikit/uitableviewdatasource阅读 UITableView 数据源协议


查看您正在阅读的教程,似乎它正在使用reloadData()强制 tableView 忽略以前的行数并使用新的行数重新加载其内容。根据您迄今为止的发现,我认为这是根本原因的一部分,表格视图错误地假设了预定的行数并试图检索不再在范围内的单元格。


推荐阅读