2015-11-03 62 views
0

我想过滤一个JSON填充UITableView,到目前为止我已经尝试了3或4个漂亮的教程,但是当我按下SearchBar时,我得到的错误都是相同的。过滤Json填充的UITableView Swift 2

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Can't use in/contains operator with collection MakeItWork.Repository (not a collection'

唯一不同于我看到的教程是我的数组在另一个文件,我从那里调用它。

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,在飞机坠毁前,因为我还没有输入任何内容,所以它会搜索一个空searchString的循环。这是正常的吗? 我查过的最后一个教程是http://www.ioscreator.com/tutorials/add-search-table-view-tutorial-ios8-swift。 我在这里错过了什么?

编辑:我认为这是正常的UISearchBar不断更新,因为我打电话UISearchResultsUpdating

回答

1

问题出在您的NSPredicate。写它的方式你尝试检查games数组contain中的对象是否为字符串。但是这个数组中的对象是Repository的实例,并且谓词无法知道它对于包含某些东西的含义。为了解决这个问题,你应该将谓词改成这样:

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

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

我写了一些关于NSPredicatehere的更长时间。

让我知道如果有什么不清楚。

+0

谢谢,让我绕过那个错误,但然后它崩溃的下一行代码与** NSForwarding:警告:对象0x7fac5bf7aa6​​0类'MakeItWork.Repository'没有实现methodSignatureForSelector: - 前面的麻烦 无法识别的选择器 - [ MakeItWork.Repository valueForKey:] ** 我读到,如果你得到那个错误,你需要把:NSObject放在你的类旁边,然后在init(){...}内放入super.init()。这给了我最后一行说**致命错误的另一个错误:阵列不能桥接Objective-C ** –

+0

我应该对当前的错误提出另一个问题,并将其标记为答案,因为您的答案解决了问题尽管出现了错误,我还是提到过? –

+0

嗯,它可能是最好的,因为更多的人会注意到你的新问题。而且我还没有使用'斯威夫特',不幸的是不知道如何进一步帮助你。 – Losiowaty