我的应用程序包含UITableViewController
,两个UIViewController
和核心数据。我想第一次发表UISearchController
。我通过这个主题查看了其他问题,但我的工作不正确UISearchController
。当我写入searchBar
时,它会给出不正确的结果。我不知道如何在表格视图中显示它们。请帮帮我。
我在UITableViewController中的代码
var resultSearchController: UISearchController!
var searchPredicate: NSPredicate?
var filteredObjects: [Note]? = nil
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.leftBarButtonItem = self.editButtonItem()
fetchedResultsController = NSFetchedResultsController(fetchRequest: allEmployeesFetchRequest(), managedObjectContext: managedObjectContext!, sectionNameKeyPath: "mynote", cacheName: "mynote") // both mynote
fetchedResultsController?.delegate = self
fetchedResultsController?.performFetch(nil)
// UISearchController setup
self.resultSearchController = ({
let controller = UISearchController(searchResultsController: nil)
controller.delegate = self
controller.searchResultsUpdater = self
controller.hidesNavigationBarDuringPresentation = false
controller.dimsBackgroundDuringPresentation = true
controller.searchBar.sizeToFit()
controller.searchBar.delegate = self
self.tableView.tableHeaderView = controller.searchBar
return controller
})()
self.tableView.reloadData()
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
let searchText = self.resultSearchController.searchBar.text
println(searchText)
if let searchText = searchText {
searchPredicate = NSPredicate(format: "mynote contains[c] %@", searchText)
filteredObjects = self.fetchedResultsController?.fetchedObjects?.filter() {
return self.searchPredicate!.evaluateWithObject($0)
} as! [Note]?
self.tableView.reloadData()
println(searchPredicate)
}
}
和
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
if searchPredicate == nil {
return fetchedResultsController?.sections?.count ?? 0
} else {
return 1
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchPredicate == nil {
return fetchedResultsController?.sections?[section].numberOfObjects ?? 0 //0 default
} else {
return filteredObjects?.count ?? 0
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CellNote", forIndexPath: indexPath) as! UITableViewCell
if searchPredicate == nil {
if var cellContact = fetchedResultsController?.objectAtIndexPath(indexPath) as? Note {
cell.textLabel?.text = cellContact.mynote
cell.detailTextLabel?.text = cellContact.mytime
return cell
}
}
return cell
}
我的核心数据类有
import Foundation
import CoreData
@objc(Note)
class Note: NSManagedObject {
@NSManaged var mynote: String
@NSManaged var mytime: String
}
答案 0 :(得分:1)
我有一个用于多个查询的类,我只是传递一个谓词,有时候是一个排序,并返回一个实体类的对象数组。我希望它有所帮助:
class QueryDatabase: NSObject {
private var _managedObjectContext: NSManagedObjectContext?
init(managedObjectContext: NSManagedObjectContext){
super.init()
_managedObjectContext = managedObjectContext
}
func QueryTable(entityName: String, sortBy: String?, ascending: Bool, searchPredicate: NSPredicate?) -> AnyObject?{
if _managedObjectContext != nil {
let fetchRequest = NSFetchRequest(entityName: entityName)
if(sortBy != nil){
let sort = NSSortDescriptor(key: sortBy!, ascending: ascending)
fetchRequest.sortDescriptors = [sort]
}
if(searchPredicate != nil){
fetchRequest.predicate = searchPredicate!
}
var err: NSError?
if let fetchResults = _managedObjectContext!.executeFetchRequest(fetchRequest, error: &err){
return fetchResults
}else{
NSLog("ERROR:\(err?.description)")
}
}
return nil
}
}
我已将它与searchBar结合使用但在我的情况下,我的谓词在其定义中添加了另一个修饰符[cd]:
func findPricesBySearchCriteria(searchCriteria: String) -> [Prices]{
if(_managedObjectContext != nil){
let queryDatabase = QueryDatabase(managedObjectContext: _managedObjectContext!)
if let results = queryDatabase.QueryTable("Prices", sortBy: "item_description", ascending: true, searchPredicate: NSPredicate(format: "item_description contains[cd] %@", searchCriteria)) as? [Prices]{
arrSearch = results
}
}
return arrSearch
}
答案 1 :(得分:0)
我找到了解决办法,我改变了我的UITableViewController
class FirstTableViewController: UITableViewController, NSFetchedResultsControllerDelegate, UITableViewDataSource, UITableViewDelegate, UISearchControllerDelegate, UISearchResultsUpdating, UISearchBarDelegate
{
@IBAction func addNew(sender: UIBarButtonItem) {
}
let managedObjectContext: NSManagedObjectContext? = (UIApplication.sharedApplication().delegate as? AppDelegate)?.managedObjectContext
var fetchedResultsController: NSFetchedResultsController?
// MARK: - setting for search controller
var searchController: UISearchController!
var searchPredicate: NSPredicate!
var filteredObjects: [Note]? = nil
var filteredDataFromObjects = [String]()
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.leftBarButtonItem = self.editButtonItem()
fetchedResultsController = NSFetchedResultsController(fetchRequest: allEmployeesFetchRequest(), managedObjectContext: managedObjectContext!, sectionNameKeyPath: "mynote", cacheName: "mynote") // both mynote
fetchedResultsController?.delegate = self
fetchedResultsController?.performFetch(nil)
self.searchController = ({
var controllerS = UISearchController(searchResultsController: nil)
controllerS.delegate = self
controllerS.searchBar.delegate = self
controllerS.searchResultsUpdater = self
controllerS.searchBar.sizeToFit()
controllerS.dimsBackgroundDuringPresentation = false
controllerS.hidesNavigationBarDuringPresentation = false
// self.definesPresentationContext = true
self.tableView.tableHeaderView = controllerS.searchBar
return controllerS
})()
}
override func viewWillAppear(animated: Bool) {
super.viewWillAppear(animated)
self.tableView.reloadData()
}
func updateSearchResultsForSearchController(searchController: UISearchController) {
filteredDataFromObjects.removeAll(keepCapacity: false)
var searchText = searchController.searchBar.text
if var searhText = searchText {
searchPredicate = NSPredicate(format: "mynote contains[c] %@", searchText)
filteredObjects = self.fetchedResultsController?.fetchedObjects?.filter() {
return self.searchPredicate.evaluateWithObject($0)
} as! [Note]?
self.tableView.reloadData()
println("Search Predicate \(searchPredicate)")
}
}
func allEmployeesFetchRequest() -> NSFetchRequest {
var fetchRequest = NSFetchRequest(entityName: "Note")
let sortDescriptor = NSSortDescriptor(key: "mytime", ascending: false) // change on date
fetchRequest.predicate = nil
fetchRequest.sortDescriptors = [sortDescriptor]
fetchRequest.fetchBatchSize = 20
return fetchRequest
}
//MARK: UITableView Data Source and Delegate Functions
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
if searchPredicate == nil {
return fetchedResultsController?.sections?.count ?? 0 //after 0
} else {
return 1 ?? 0
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchPredicate == nil {
return fetchedResultsController?.sections?[section].numberOfObjects ?? 0 //0 default
} else {
return filteredObjects?.count ?? 0
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("CellNote", forIndexPath: indexPath) as! UITableViewCell
if searchPredicate == nil {
if var cellContact = fetchedResultsController?.objectAtIndexPath(indexPath) as? Note {
cell.textLabel?.text = cellContact.mynote
cell.detailTextLabel?.text = cellContact.mytime
}
} else {
if var textFromFiltered = filteredObjects?[indexPath.row] {
cell.textLabel?.text = textFromFiltered.mynote
cell.detailTextLabel?.text = textFromFiltered.mytime
}
}
return cell
}
//MARK: NSFetchedResultsController Delegate Functions
func controller(controller: NSFetchedResultsController, didChangeSection sectionInfo: NSFetchedResultsSectionInfo, atIndex sectionIndex: Int, forChangeType type: NSFetchedResultsChangeType) {
var tableView = UITableView()
if searchPredicate == nil {
tableView = self.tableView
} else {
tableView = (searchController.searchResultsUpdater as! FirstTableViewController).tableView
}
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) {
if editingStyle == .Delete {
}
switch editingStyle {
case .Delete:
managedObjectContext?.deleteObject(fetchedResultsController?.objectAtIndexPath(indexPath) as! Note)
managedObjectContext?.save(nil)
case .Insert:
break
case .None:
break
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
// I made test which controller is need to show
var tableView = UITableView()
if searchPredicate == nil {
tableView = self.tableView
} else {
tableView = (searchController.searchResultsUpdater as! FirstTableViewController).tableView
}
switch type {
case NSFetchedResultsChangeType.Insert:
tableView.insertRowsAtIndexPaths([AnyObject](), withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Delete:
tableView.deleteRowsAtIndexPaths(NSArray(object: indexPath!) as [AnyObject], withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Move:
tableView.deleteRowsAtIndexPaths(NSArray(object: indexPath!) as [AnyObject], withRowAnimation: UITableViewRowAnimation.Fade)
tableView.insertRowsAtIndexPaths(NSArray(object: newIndexPath!) as [AnyObject], withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Update:
tableView.cellForRowAtIndexPath(indexPath!)
break
default:
break
}
}
func controllerWillChangeContent(controller: NSFetchedResultsController) {
if searchPredicate == nil {
tableView.beginUpdates()
} else {
(searchController.searchResultsUpdater as? FirstTableViewController)?.tableView.beginUpdates()
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
if searchPredicate == nil {
tableView.endUpdates()
} else {
(searchController.searchResultsUpdater as? FirstTableViewController)?.tableView.endUpdates()
}
}
@IBAction func unwindToFirst(segue: UIStoryboardSegue) {
}
// for sent data in detail controller
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "showDetail" {
if let indexPath = self.tableView.indexPathForSelectedRow() {
if searchPredicate == nil {
let object = self.fetchedResultsController!.objectAtIndexPath(indexPath) as! NSManagedObject
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController //DetailViewController
controller.detailItem = object
} else {
let object = filteredObjects![indexPath.row] as Note
let controller = (segue.destinationViewController as! UINavigationController).topViewController as! DetailViewController
controller.detailItem = object
}
}
self.searchController.active = false
}
}
func configureCell(cell: UITableViewCell, atIndexPath indexPath: NSIndexPath) {
let object = self.fetchedResultsController!.objectAtIndexPath(indexPath) as! NSManagedObject
cell.textLabel!.text = object.valueForKey("mynote")!.description
}
// MARK: - UISearch functions
func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
updateSearchResultsForSearchController(searchController)
}
func didDismissSearchController(searchController: UISearchController) {
filteredObjects = nil
searchPredicate = nil
tableView.reloadData()
}
}