我是iOS开发的新手,我是第二个使用Swift的应用程序。我无法合并SearchBar&在我的表视图控制器中显示搜索。
我的应用中有2个观看次数。 First View生成一个水果阵列。第一视图的输出:[Apple,Orange,Banana,Pears]。然后[石榴,梨,西瓜,甜瓜]等。一次一个阵列。
每个水果数组都使用NSFetchedResultsController存储在核心数据中,以显示在tableviewcontroller中。 我的Coredata布局:
import UIKit
import CoreData
@objc(Fruits)
class Fruits: NSManagedObject {
@NSManaged var date: String
@NSManaged var fruit: String
}
我的第二个视图显示水果列表。现在我添加了一个搜索栏&在表格视图的顶部显示。但我无法使其发挥作用。
使用的协议:
class HistoryTableViewController: UITableViewController, NSFetchedResultsControllerDelegate{
声明的变量:
let managedObjectContext: NSManagedObjectContext? = (UIApplication.sharedApplication().delegate as? AppDelegate)?.managedObjectContext
var fetchedResultsController: NSFetchedResultsController?
var fetchRequest = NSFetchRequest(entityName: "Fruits")
我班上有两个出路:
@IBOutlet weak var searchBar: UISearchBar! // the Search Bar & Display
@IBOutlet var tblHistory: UITableView! = nil // Table View
表格视图的数据填充:
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
return fetchedResultsController?.sections?.count ?? 0
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int
{
return fetchedResultsController?.sections?[section].numberOfObjects ?? 0
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: (NSIndexPath!)) -> UITableViewCell
{
let cell = tableView.dequeueReusableCellWithIdentifier("cell", forIndexPath: indexPath) as UITableViewCell
if let cellFruit = fetchedResultsController?.objectAtIndexPath(indexPath) as? Fruits
{
cell.textLabel?.text = cellFruit.fruit
cell.detailTextLabel?.text = cellFruit.date
}
return cell
}
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return false if you do not want the specified item to be editable.
return true
}
//MARK: NSFetchedResultsController Delegate Functions
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
switch type {
case NSFetchedResultsChangeType.Insert:
tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Delete:
tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Move:
break
case NSFetchedResultsChangeType.Update:
break
default:
break
}
}
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
//Delete object from entity, remove from list
if editingStyle == .Delete {
}
switch editingStyle {
case .Delete:
managedObjectContext?.deleteObject(fetchedResultsController?.objectAtIndexPath(indexPath) as! Fruits)
do {
try managedObjectContext?.save()
}catch{}
print("Fruit set deleted successfully.")
case .Insert:
break
case .None:
break
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
switch type {
case NSFetchedResultsChangeType.Insert:
tableView.insertRowsAtIndexPaths(NSArray(object: newIndexPath!) as! [NSIndexPath], withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Delete:
tableView.deleteRowsAtIndexPaths(NSArray(object: indexPath!) as! [NSIndexPath], withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Move:
tableView.deleteRowsAtIndexPaths(NSArray(object: indexPath!) as! [NSIndexPath], withRowAnimation: UITableViewRowAnimation.Fade)
tableView.insertRowsAtIndexPaths(NSArray(object: newIndexPath!) as! [NSIndexPath], withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Update:
tableView.cellForRowAtIndexPath(indexPath!)
break
default:
break
}
}
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
如何从coredata搜索任何水果并过滤视图? 应该将哪个代理功能用于搜索栏&在Swift编码中显示功能?
对于我可能在这里错过的概念的任何帮助将不胜感激!感谢。
更新:,因为Daniel Eggert建议我尝试将谓词用于搜索控制器功能,但Predicate总是提供 nil 。我错过了什么?
在类中声明的变量:
var results: NSArray = []
var searchPredicate: NSPredicate?
var searchController: UISearchController!
谓词函数:
//Search Functionality
func updateSearchResultsForSearchController(searchController: UISearchController)
{
let searchText = self.searchController?.searchBar.text
if let searchText = searchText {
searchPredicate = NSPredicate(format: "fruit contains[cd] %@", searchText)
results = (self.fetchedResultsController!.fetchedObjects?.filter() {
return self.searchPredicate!.evaluateWithObject($0)
} as! [Fruits]?)!
self.tableView.reloadData()
}
}
// Called when text changes (including clear)
func searchBar(searchBar: UISearchBar, textDidChange searchText: String)
{
if !searchText.isEmpty
{
var predicate: NSPredicate = NSPredicate()
predicate = NSPredicate(format: "fruit contains [cd] %@", searchText)
let sortDescriptor = NSSortDescriptor(key: "date", ascending: true)
fetchRequest.sortDescriptors = [sortDescriptor]
fetchedResultsController?.fetchRequest.predicate? = predicate
print(fetchedResultsController?.fetchRequest.predicate) // this is always nil. Why????????????
do {
try fetchedResultsController?.performFetch()
}catch{}
print("results array: \(results)") // this array should have values of the table view, but is empty. Why ?????????????????
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: managedObjectContext!,
sectionNameKeyPath: "fruit", cacheName: nil)
fetchedResultsController?.delegate = self
tableView.reloadData()
}
}
答案 0 :(得分:0)
您想在获取的结果控制器上设置谓词。
在获取的结果控制器上更改了获取请求后,您需要调用performFetch()
让它重新获取其数据。然后在表格视图上调用reloadData()
。
由于语言,区域设置和Unicode的交互方式,文本搜索非平凡的示例可能很难做到正确。我推荐书中的 Text 章节:https://www.objc.io/books/core-data/
答案 1 :(得分:0)
如果要实现可搜索的tableView?您必须使用UISearchResultsUpdating
协议方法而不是名为UISearchBarDelegate
的{{1}}协议方法。当searchBar:textDidChange
协议方法不可用时,您可以使用searchBar:textDidChange
方法!这两个类都很有用且功能强大。并且易于实施