Swift - 使用带有结构数组的 UISearchController 和 NSPredicate 进行搜索
Swift - Search using UISearchController and NSPredicate with an array of structs
目前我正在尝试为我的 tableView 设置一个搜索栏。我想用 NSPredicate 过滤用户的输入,以显示来自结构对象数组的过滤数据。
但是当我尝试在这样的数组上调用 .filteredArrayUsingPredicate()
时,出现以下错误 [Course] is not convertible to 'NSArray'
。
下面是我的代码和回购的 link。我也愿意接受任何更好的方法。
import UIKit
import SwiftyJSON
class CourseTableViewController: UITableViewController, UISearchResultsUpdating {
var allCourses: [Course] = [Course]()
var searchArray: [Course] = [Course]() {
didSet {
self.tableView.reloadData()
}
}
var resultSearchController = UISearchController()
override func viewDidLoad() {
super.viewDidLoad()
retrieveCourses()
configureView()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func configureView() {
tableView.rowHeight = 50
// Search Controller Initialization
self.resultSearchController = UISearchController(searchResultsController: nil)
resultSearchController.searchResultsUpdater = self
resultSearchController.hidesNavigationBarDuringPresentation = false
resultSearchController.dimsBackgroundDuringPresentation = false
resultSearchController.searchBar.searchBarStyle = .Minimal
resultSearchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = resultSearchController.searchBar
}
func retrieveCourses() {
APIService.getAllCourses() { (data) -> Void in
for courseIndex in data {
var course: Course = Course(courseJSON: courseIndex.1)
self.allCourses.append(course)
println("Course Index: " + String(self.allCourses.count))
}
self.sortAllCourses()
}
}
func sortAllCourses() {
allCourses.sort() {[=11=].abbr < .abbr}
self.tableView.reloadData()
}
// MARK: - Search
func updateSearchResultsForSearchController(searchController: UISearchController) {
self.searchArray.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text)
// ERROR is on this line
let filteredArray: Array = (allCourses as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.searchArray = filteredArray as [Course]
}
// Full tableView code can be found in the repo
}
Link: https://github.com/classmere/app/tree/feature/issue/1/implementSearch
非常感谢!
所以在四处寻找之后,我发现对于这种情况更好的方法是简单地使用 .filter() 和 .rangeOfString() 来解决这个问题
theArray.filter() { [=10=].json?.rangeOfString(searchQuery, options: .CaseInsensitiveSearch) != nil}
虽然没有使用 NSPredicate,但对于我当前的设置来说这似乎是一个更容易实现的方法。
目前我正在尝试为我的 tableView 设置一个搜索栏。我想用 NSPredicate 过滤用户的输入,以显示来自结构对象数组的过滤数据。
但是当我尝试在这样的数组上调用 .filteredArrayUsingPredicate()
时,出现以下错误 [Course] is not convertible to 'NSArray'
。
下面是我的代码和回购的 link。我也愿意接受任何更好的方法。
import UIKit
import SwiftyJSON
class CourseTableViewController: UITableViewController, UISearchResultsUpdating {
var allCourses: [Course] = [Course]()
var searchArray: [Course] = [Course]() {
didSet {
self.tableView.reloadData()
}
}
var resultSearchController = UISearchController()
override func viewDidLoad() {
super.viewDidLoad()
retrieveCourses()
configureView()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
func configureView() {
tableView.rowHeight = 50
// Search Controller Initialization
self.resultSearchController = UISearchController(searchResultsController: nil)
resultSearchController.searchResultsUpdater = self
resultSearchController.hidesNavigationBarDuringPresentation = false
resultSearchController.dimsBackgroundDuringPresentation = false
resultSearchController.searchBar.searchBarStyle = .Minimal
resultSearchController.searchBar.sizeToFit()
self.tableView.tableHeaderView = resultSearchController.searchBar
}
func retrieveCourses() {
APIService.getAllCourses() { (data) -> Void in
for courseIndex in data {
var course: Course = Course(courseJSON: courseIndex.1)
self.allCourses.append(course)
println("Course Index: " + String(self.allCourses.count))
}
self.sortAllCourses()
}
}
func sortAllCourses() {
allCourses.sort() {[=11=].abbr < .abbr}
self.tableView.reloadData()
}
// MARK: - Search
func updateSearchResultsForSearchController(searchController: UISearchController) {
self.searchArray.removeAll(keepCapacity: false)
let searchPredicate = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text)
// ERROR is on this line
let filteredArray: Array = (allCourses as NSArray).filteredArrayUsingPredicate(searchPredicate)
self.searchArray = filteredArray as [Course]
}
// Full tableView code can be found in the repo
}
Link: https://github.com/classmere/app/tree/feature/issue/1/implementSearch
非常感谢!
所以在四处寻找之后,我发现对于这种情况更好的方法是简单地使用 .filter() 和 .rangeOfString() 来解决这个问题
theArray.filter() { [=10=].json?.rangeOfString(searchQuery, options: .CaseInsensitiveSearch) != nil}
虽然没有使用 NSPredicate,但对于我当前的设置来说这似乎是一个更容易实现的方法。