过滤Json填充的UITableView Swift 2

时间:2015-11-03 13:36:07

标签: ios json swift uitableview uisearchbar

我正在尝试过滤一个填充了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时始终保持更新是正常的。

1 个答案:

答案 0 :(得分:1)

问题在于您的NSPredicate。编写它的方式是尝试检查games数组contain中的对象是否为字符串。但是这个数组中的对象是Repository的实例,而谓词无法知道Repository包含某些内容的含义。要解决此问题,您应该将谓词更改为:

NSPredicate(format: "SELF.name CONTAINS[c] %@",searchString)

这样,谓词将检查name实例的Repository属性是否包含提供的搜索字符串。

我写了一篇关于NSPredicate here的文章。

如果不清楚,请告诉我。