我正在尝试过滤一个填充了JSON的UITableView
,到目前为止,我已经尝试了3或4个相当不错的教程,但是当我按下SearchBar
时,我在所有这些教程上都遇到了相同的错误。
由于未捕获的异常而终止应用 'NSInvalidArgumentException',原因:'无法使用in / contains运算符 与集合MakeItWork.Repository(不是集合'
唯一与我看到的教程不同的是,我的Array在另一个文件上,我从那里调用它。
Repository.swift
class Repository {
var name: String?
var releaseDate: String?
var gameImage: String?
var id: String?
init(json: NSDictionary) {
self.name = json["name"] as? String
self.releaseDate = json["release_date"] as? String
self.gameImage = json["image"] as? String
self.id = json["_id"] as? String
}
}
GameTableViewController.swift
var games = [Repository]()
var filteredTableData = [String]()
var shouldShowSearchResults = false
var searchController: UISearchController!
func configureSearchController() {
// Initialize and perform a minimum configuration to the search controller.
searchController = UISearchController(searchResultsController: nil)
searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search here..."
searchController.searchBar.delegate = self
searchController.searchBar.sizeToFit()
// Place the search bar view to the tableview headerview.
self.tableView.tableHeaderView = searchController.searchBar
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
let searchString = searchController.searchBar.text!
filteredTableData.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@",searchString)
let array = (games as NSArray).filteredArrayUsingPredicate(searchPredicate)
filteredTableData = array as! [String]
self.tableView.reloadData()
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if shouldShowSearchResults {
return filteredTableData.count
}
else {
return games.count
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cellIdentifier = "GameTableViewCell"
let cell = tableView.dequeueReusableCellWithIdentifier(cellIdentifier, forIndexPath: indexPath) as! GameTableViewCell
if (shouldShowSearchResults) {
cell.nameLabel?.text = filteredTableData[indexPath.row]
return cell
}
else {
cell.nameLabel?.text = games[indexPath.row].name
cell.releaseDateLabel?.text = games[indexPath.row].releaseDate
if let url = NSURL(string: self.games[indexPath.row].gameImage!) {
cell.photoImageView?.hnk_setImageFromURL(url)
}
}
return cell
}
我在updateSearchResultsForSearchController的开头设置了一个断点,我注意到每次按下UISearchBar,在崩溃之前,它都会使用null searchString进行搜索循环,因为我还没有输入任何内容。这是正常的吗? 我检查的最后一个教程是http://www.ioscreator.com/tutorials/add-search-table-view-tutorial-ios8-swift。 我在这里缺少什么?
编辑:我认为UISearchBar在调用UISearchResultsUpdating
时始终保持更新是正常的。
答案 0 :(得分:1)
问题在于您的NSPredicate
。编写它的方式是尝试检查games
数组contain
中的对象是否为字符串。但是这个数组中的对象是Repository
的实例,而谓词无法知道Repository
包含某些内容的含义。要解决此问题,您应该将谓词更改为:
NSPredicate(format: "SELF.name CONTAINS[c] %@",searchString)
这样,谓词将检查name
实例的Repository
属性是否包含提供的搜索字符串。
我写了一篇关于NSPredicate
here的文章。
如果不清楚,请告诉我。