Arrays 如何在Swift 3中搜索对象数组
我试图搜索从Firebase数据库中提取的对象数组。数据加载正常,但当我尝试搜索时,没有显示任何内容。我学习iOS/Swift开发才6周左右。下面是我的代码 我一点击搜索栏,应用程序就崩溃了。Arrays 如何在Swift 3中搜索对象数组,arrays,swift,object,search,Arrays,Swift,Object,Search,我试图搜索从Firebase数据库中提取的对象数组。数据加载正常,但当我尝试搜索时,没有显示任何内容。我学习iOS/Swift开发才6周左右。下面是我的代码 我一点击搜索栏,应用程序就崩溃了。 我设法让搜索代码停止崩溃,但我在搜索中没有得到任何回报。这是因为我正在搜索Firebase数据库吗?我正在将firebase数据加载到一个数组中,所以它应该是可搜索的,对吗 import UIKit import Firebase class ServicesTableViewController: U
我设法让搜索代码停止崩溃,但我在搜索中没有得到任何回报。这是因为我正在搜索Firebase数据库吗?我正在将firebase数据加载到一个数组中,所以它应该是可搜索的,对吗
import UIKit
import Firebase
class ServicesTableViewController: UITableViewController, UISearchResultsUpdating {
var services = [Service]()
var filteredSearch = [Service]()
var searchController: UISearchController!
var resultsController = UITableViewController()
override func viewDidLoad() {
super.viewDidLoad()
// Turn this back on to cache data
FIRDatabase.database().persistenceEnabled = true
fetchServices()
self.resultsController.tableView.dataSource = self
self.resultsController.tableView.delegate = self
self.searchController = UISearchController(searchResultsController: self.resultsController)
self.tableView.tableHeaderView = searchController.searchBar
self.searchController.searchResultsUpdater = self
searchController.dimsBackgroundDuringPresentation = false
searchController.searchBar.placeholder = "Search services..."
searchController.searchBar.tintColor = UIColor.white
searchController.searchBar.barTintColor = UIColor(red: 164.0/255.0, green: 45.0/255.0, blue: 9.0/255.0, alpha: 1.0)
navigationItem.backBarButtonItem = UIBarButtonItem(title: " ", style: .plain, target: nil, action: nil)
}
// MARK: - Search Controller
func filterContent(for searchText: String) {
filteredSearch = services.filter({ (service) -> Bool in
if let name = service.name {
let isMatch = name.localizedCaseInsensitiveContains(searchText)
return isMatch
}
return false
})
}
func updateSearchResults(for searchController: UISearchController) {
if let searchText = searchController.searchBar.text {
filterContent(for: searchText)
tableView.reloadData()
}
}
// MARK: Database connection and data fetch
func fetchServices () {
FIRDatabase.database().reference().child("services").observe(.childAdded, with: { (snapshot) in
print(snapshot)
if let dictionary = snapshot.value as? [String: AnyObject] {
let service = Service()
service.setValuesForKeys(dictionary)
self.services.append(service)
self.tableView.reloadData()
}
})
}
// MARK: - Table view data source
override func numberOfSections(in tableView: UITableView) -> Int {
return 1
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchController.isActive {
return filteredSearch.count
} else {
return services.count
}
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cellIdentifier = "Cell"
let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! ServicesTableViewCell
// Check to see if the user is searching or not
let service = (searchController.isActive) ? filteredSearch[indexPath.row] : services[indexPath.row]
// let service = services[indexPath.row]
cell.programLabel.text = service.name
cell.programLabel.font = UIFont(name: "Avenir-Medium", size: 18.0)
cell.programLabel.textColor = UIColor(red: 0.0/255.0, green: 0.0/255.0, blue: 0.0/255.0, alpha: 1.0)
cell.branchLabel.text = service.branch
cell.branchLabel.font = UIFont(name: "Avenir-Medium", size: 14.0)
cell.branchLabel.textColor = UIColor(red: 90.0/255.0, green: 86.0/255.0, blue: 92.0/255.0, alpha: 1.0)
cell.servicesLabel.text = service.shortDesc
cell.servicesLabel.font = UIFont(name: "Avenir-Light", size: 14.0)
cell.servicesLabel.textColor = UIColor(red: 164.0/255.0, green: 45.0/255.0, blue: 9.0/255.0, alpha: 1.0)
cell.thumbnailImageView.image = UIImage(named: service.imageName!)
return cell
}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
if segue.identifier == "showServicesDetail" {
if let indexPath = tableView.indexPathForSelectedRow {
let destinationController = segue.destination as! ServicesDetailViewController
destinationController.services = services[indexPath.row]
}
}
}
}
这是我目前的故事板。只有两个视图和一个导航控制器,
我假设您要按名称搜索:
filteredSearch = services.filter { (service: Service) -> Bool in
if let name = service.name,
let searchText = self.searchController.searchBar.text?.lowercased() {
return name.lowercased().contains(searchText)
} else {
return false
}
}
另外,让我们将filteredSearch
更改为服务的数组
:
var filteredSearch = [Service]()
如果您的
服务
类别如下
class Service: NSObject {
var serviceID: NSInteger!
var serviceName: String!
}
您可以使用包含self.searchController.searchBar.text的serviceName
检索筛选器服务
let fiterServices = services.filter({$0.serviceName.lowercased().range(of: self.searchController.searchBar.text!.lowercased()) != nil})
希望这有帮助。我有一个对象数组(codeDataObjectList)
下面的代码可以搜索每个对象中的文本,您可以使用filteredTableData
func updateSearchResults(for searchController: UISearchController) {
filteredTableData.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "code CONTAINS[c] %@ OR longDescription CONTAINS[c] %@ OR shortDescription CONTAINS[c] %@", searchController.searchBar.text!, searchController.searchBar.text!, searchController.searchBar.text!)
let array = (self.codeDataObjectList as NSArray).filtered(using: searchPredicate)
filteredTableData = array as! [CodeDataObject]
self.tableView.reloadData()
}
因为
services.filter
将返回Service
的数组,但filteredSearch
是字符串的数组。为什么不var filteredSearch=[Service]()
?您需要向我们展示您的服务
课程非常感谢您的建议。我对var filteredSearch=[Service]()进行了更改,但是我遇到了一个错误,无法将(string)->Bool的值转换为预期的参数类型(Service)->Bool。这是我创建的类。文件名“Service.swift”导入UIKit类服务:NSObject{var name:String?var branch:String?var shortDesc:String?var longDesc:String?var imageName:String?var mainPhone:String?var位置:String?var小时数:String?var网站:String?}我正在使用此链接中的教程。在我完成定制课程之前,我一直工作得很好。谢谢,丹。我尝试了你的代码,它构建得很好,没有错误,但当我点击搜索程序进行搜索时,应用程序因SIGABRT错误而崩溃(Danh,这是控制台的错误。2017-04-03 19:59 MCCSServicesGuide[64700:9332471]***在[UITableView dequeueReusableCellWithIdentifier:forIndexPath:]、/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKit_Sim/UIKit-3600.7.47/UITableView.m:6730 2017-04-03 19:59:19.336 MCCSServicesGuide[64700:9332471]中的断言失败***由于未捕获的异常“NSInternalInconsistencyException”而终止应用程序,原因:“无法将具有标识符单元格的单元格出列-必须为标识符注册nib或类,或在情节提要中连接原型单元格”***第一次抛出调用堆栈:我想tableView找不到“单元格”标识符。如果可能的话,让我看看你的故事板和代码。我刚刚编辑了我的帖子,并将tableviewcontroller中的所有当前代码加上自定义类。你是否忘记了为故事板中的ServiceStablevewCell
单元格设置identifier
?在Main.storyboard中选择你的单元格,然后选择Att右侧的ributes inspector,并在标识符
框中设置单元格
。谢谢你,Sree。当我尝试你的代码时,我得到了一个错误“行上的连续状态必须用分隔符分隔”;我可能做了一些我想做的事情sure@ShootLighter:我进行了编辑。请查看代码(删除了nil旁边的右括号和$0.serviceName之间的空格)@ShootLighter如果解决了您的问题,请接受答案。我喜欢这个解决方案,因为它使我能够搜索多个字段,但我在理解如何在代码中实现它时遇到一些困难。抱歉,我确定是我,因为我是新来的。我刚刚发布了tableviewcontroller的所有代码。如果您不介意,我将如何实现这段代码使用了我的数组、变量和类。?如果这不合理,很抱歉,谢谢大家的帮助。我设法让搜索代码停止崩溃,但我在搜索中没有得到任何回报。这是因为我在搜索Firebase数据库吗?我正在将Firebase数据加载到一个数组中,因此它应该可以搜索,对吗?这就是为什么您推荐使用NSPredicate?提前感谢您的帮助。对不起,我不知道
func updateSearchResults(for searchController: UISearchController) {
filteredTableData.removeAll(keepingCapacity: false)
let searchPredicate = NSPredicate(format: "code CONTAINS[c] %@ OR longDescription CONTAINS[c] %@ OR shortDescription CONTAINS[c] %@", searchController.searchBar.text!, searchController.searchBar.text!, searchController.searchBar.text!)
let array = (self.codeDataObjectList as NSArray).filtered(using: searchPredicate)
filteredTableData = array as! [CodeDataObject]
self.tableView.reloadData()
}