我遇到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 $0.gameName.range(of: searchBar.searchBar.text!) != nil
}
updateSearchResults(for: searchBar)
self.tableView.reloadData()
}
我遇到了这个错误:return $0.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
答案 0 :(得分:1)
我在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 = $0.gameName
let stringToCompare = searchBar.searchBar.text!
if let range = strGameName.range(of: stringToCompare) {
return true
} else {
return false
}
}
tableView.reloadData()
}
}
这解决了崩溃并在tableView
中加载filteredArray的数据答案 1 :(得分:0)
此方法使用 UISearchBar 而不是swift 4的 UISearchBarController ,因为UISearchBarController 不适用于iOS 10 (许多设备仍使用iOS 10 )。
使您的班级符合 UISearchBarDelegate
为数组定义你的var&检查是否搜索:
var gameList = [gameStruct]()
var filteredGameList = [gameStruct]()
var inSearchMode = false
为UISearchBar创建出口
@IBOutlet weak var searchBar: UISearchBar!
在viewDidLoad中,为searchBar设置委托
searchBar.delegate = self
searchBar.returnKeyType = .done
实施委托方法
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()
}
}
实现tableView Delegates
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()
}
答案 2 :(得分:0)
也许它非常简单,但在你的
中return $0.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 !$0.gameName.range(of: text) != nil
}
如果这是解决方案,我会有点困惑,因为通常Xcode会抛出一条错误消息,如unexpectedly found nil while unwrapping a optional value
。你介意试试吗?