搜索栏搜索问题

issue with searchBar searching

我对 UISearchBar 实施有疑问。我已经完成了必须的工作,但是当我尝试在 tableView 中搜索时遇到问题

struct gameStruct: Codable {
    var id: String
    var image: String
    var gameName: String
    var gameDate: String
    var gameVideo: String

}
var filteredArray : [gameStruct] = []
var searchBar :UISearchController!
var shouldShowSearchResults = false

func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
    shouldShowSearchResults = true
    //tableView.reloadData()
}

func searchBarCancelButtonClicked(_ searchBar: UISearchBar) {
    shouldShowSearchResults = false
    //tableView.reloadData()
}

func searchBarSearchButtonClicked(_ searchBar: UISearchBar) {
    if !shouldShowSearchResults {
        shouldShowSearchResults = true
        //tableView.reloadData()
    }

    searchBar.resignFirstResponder()
}

func updateSearchResults(for searchController: UISearchController) {
    filteredArray = gameV3.filter() {
        return [=10=].gameName.range(of: searchBar.searchBar.text!) != nil
    }
    updateSearchResults(for: searchBar)

    self.tableView.reloadData()
}

我在行中遇到了这个错误:return [=12=].gameName.range(of: searchBar.searchBar.text!) != nil

Thread 1: EXC_BAD_ACCESS (code=2, address=0x7ffee1c0aff8)

GITHUB 上的完整代码:https://github.com/iYousef911/UTGupToGame/blob/master/gameTableViewController.swift

此方法使用 UISearchBar 而不是 swift 4 的 UISearchBarController 因为 UISearchBarController 不适用于 iOS 10(很多设备仍然使用iOS 10)。

  1. 让你的class符合UISearchBarDelegate

  2. 为数组和检查是否搜索定义变量:

    var gameList = [gameStruct]() 
    var filteredGameList = [gameStruct]()
    var inSearchMode = false
    
  3. 为 UISearchBar 创建出口

    @IBOutlet weak var searchBar: UISearchBar!
    
  4. 在viewDidLoad中,为searchBar设置委托

    searchBar.delegate = self
    searchBar.returnKeyType = .done
    
  5. 实现委托方法

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) {
        if searchBar.text == nil || searchBar.text == "" {
            inSearchMode = false
            // to dismiss keyboard
            view.endEditing(true)
            tableView.reloadData()
        }else{
            inSearchMode = true
            let lower = searchBar.text!.lowercased()
            filteredGameList = gameList.filter({ (game: GameStruct) -> Bool in
                return (game.gameName?.lowercased().contains(lower))!
            })
            tableView.reloadData()
        }
    }
    
  6. 实施 tableView 委托

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if inSearchMode {
            return filteredGameList.count
        }
       return gameList.count
    }
    
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        if let cell = tableView.dequeueReusableCell(withIdentifier: "yourIdentifier", for: indexPath) as? YourCustomCell {
            let game: GameStruct!
            if inSearchMode {
                game = filteredGameList[indexPath.row]
            } else {
                game = gameList[indexPath.row]
            }
            return cell
        }
        return UITableViewCell()
    }
    

也许这很简单,但在你的内心

return [=10=].gameName.range(of: searchBar.searchBar.text!) != nil

你强制 Xcode 解包 searchBar.text 的值,这是一个可选的值,然后在解包后检查它是否为零。

尝试使用类似这样的方式轻轻展开 searchBar.text

filteredArray = gameV3.filter() {
    guard let text = searchBar.searchBar.text else {
        return false
    }
    return ![=11=].gameName.range(of: text) != nil
}

如果这是解决方案,我会有点困惑,因为通常 Xcode 会抛出类似 unexpectedly found nil while unwrapping a optional value 的错误消息。你介意试试吗?

我在 GitHub 上看到了您的代码并尝试解决崩溃问题。这就是我对您的 updateSearchResults() 所做的。我已经使用了您在问题中提到的代码并演示了其中的更改。你可以相应地改变。

func updateSearchResults(for searchController: UISearchController) {
        if searchBar.searchBar.text == nil || searchBar.searchBar.text == "" {
            inSearchMode = false
            view.endEditing(true)
            tableView.reloadData()
        }else{
            inSearchMode = true
            filteredArray = gameV3.filter() {
                
                let strGameName = [=10=].gameName
                let stringToCompare = searchBar.searchBar.text!
                
                if let range = strGameName.range(of: stringToCompare) {
                    return true
                } else {
                    return false
                }
            }
            
            tableView.reloadData()
        }
        
    }

解决了在tableView中加载filteredArray数据的崩溃问题