如何过滤 '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
.
实现类似的东西
我一直在兜圈子试图在我的 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
.