如何过滤 'updateSearchResultsForSearchController' 中的字典数组以使用 Swift 搜索 UITableView

How can I filter an array of dictionaries in 'updateSearchResultsForSearchController' to search a UITableView with Swift

我一直在兜圈子试图在我的 UITableView 中实现搜索功能。

我已经按照 Whosebug 上的大量说明进行操作,并在 YouTube 上观看了大量视频,我觉得我现在知道如何实现 UISearchController 但我正在努力如何在 updateSearchResultsForSearchController函数。

如果我有一个简单的字符串值数组,就像您在大多数实现搜索的在线示例中看到的那样,我已经设法使搜索工作,但我有一个字典数组,但不知道如何使用 .filter 获取字典中的 key/value 对。

我的 peopleData 数组是来自 JSON 文件的字典数组,如下所示:

{
  "people": [
  {
    "ID" : "1",
    "firstname" : "Bob",
    "lastname" : "Smith",
    "age" : 25,
    "gender" : "Male"
  },
  {
    "ID" : "2",
    "firstname" : "Fred",
    "lastname" : "Smith",
    "age" : "52",
    "gender" : "Male"
  }
           ]
}  


我的视图控制器如下所示:

//  Created by Elliot Wainwright on 26/02/2016.  
//  Copyright © 2016 Elliot Wainwright. All rights reserved.

import UIKit

class SelectPersonTableViewController: UITableViewController {

    var myList:NSMutableArray = []
    var personData:NSMutableArray = []
    var filteredPeopleData:NSMutableArray = []

    var searchController : UISearchController!
    var resultsController = UITableViewController()

    @IBOutlet var selectPersonTable: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()

        guard let path = NSBundle.mainBundle().pathForResource("PeopleData", ofType: "json") else {
            print("error finding file")
            return
        }

        do {
            let data: NSData? = NSData(contentsOfFile: path)
            if let jsonResult: NSDictionary =
                try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary {
                    personData = jsonResult["people"] as! NSMutableArray
                }
            } catch let error as NSError {
                print("Error:\n \(error)")
                return
            }

        self.resultsController.tableView.dataSource = self
        self.resultsController.tableView.delegate = self

        self.searchController = UISearchController(searchResultsController: self.resultsController)
        self.tableView.tableHeaderView = self.searchController.searchBar
        self.searchController.searchResultsUpdater = self
        definesPresentationContext = true

        selectPersonTable.reloadData()
    }

    func updateSearchResultsForSearchController(searchController: UISearchController) {
        //Filter through the array

            //---------------------------------------------
            //I have no idea how to do this for my array!!!
            //---------------------------------------------

        //Update the results TableView
        self.resultsController.tableView.reloadData()
    }
    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        if tableView == self.tableView {
            return self.peopleData.count
        } else {
            return self.filteredPeopleData.count
        }
    }

    override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath)

        if tableView == self.tableView {
            for person in personData {
                let thisPerson = personData.objectAtIndex(indexPath.row)
                cell.textLabel?.text = thisPerson["person"] as? String
            }
        } else {
            for person in filteredPeopleData {
                let thisPerson = filteredPeopleData.objectAtIndex(indexPath.row)
                cell.textLabel?.text = thisPerson["person"] as? String
            }
        }

        return cell
    }

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        myList.addObject(personData.objectAtIndex(indexPath.row))
        navigationController?.popViewControllerAnimated(true)
    }

    // MARK: - Navigation

    override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
        var vc = segue.destinationViewController as! ViewController
        vc.peopleList = myList
    }
}


如您所见,在 ViewDidLoad 中,我在 'people' personData = jsonResult["people"] as! NSMutableArray 中获取了 JSON 文件的内容,因此我得到了一个字典数组。

理想情况下,用户将能够在 UISearchBar 中键入内容,并且数组(因此 table)将被过滤以显示包含任何值的任何元素,这些值包括用户键入内容的一部分.因此,键入 "ith" 会 return 两行,因为 'ith' 出现在 'Smith' 中,用于数组中的两个元素。

至少,我希望能够搜索至少一个 key/value。

试试这个:

let results = personData.filter({ person in
    if let firstname = person["firstname"] as? String, lastname = person["lastname"] as? String, query = searchController.searchBar.text {
        return firstname.rangeOfString(query, options: [.CaseInsensitiveSearch, .DiacriticInsensitiveSearch]) != nil || lastname.rangeOfString(query, options: [.CaseInsensitiveSearch, .DiacriticInsensitiveSearch]) != nil
    }
    return false
})
filteredPeopleData = NSMutableArray(array: results)

这会筛选出匹配 firstname 属性 的人。您可以为 lastname.

实现类似的东西