我有UISearchController
并且它只返回第一个结果,但Core Data有几个结果。
我做了很多不同的变种,但他们没有帮助我。
否则UISearchController
会返回错误的结果。
import UIKit
import Foundation
import CoreData
class SongTableVC: UITableViewController, UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate, UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating {
// MARK: - var and let
var appDel = (UIApplication.sharedApplication().delegate as! AppDelegate)
var context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!
// MARK: - NSFetchedResultsController and its functions
var fetchedResultsController: NSFetchedResultsController!
func returnRequest() -> NSFetchRequest {
var fetchRequest = NSFetchRequest(entityName: "Song")
var sort = NSSortDescriptor(key: "songName", ascending: false)
fetchRequest.fetchBatchSize = 50
fetchRequest.predicate = nil
fetchRequest.sortDescriptors = [sort]
return fetchRequest
}
// MARK: - UISearchController and its fucntions
var searchController: UISearchController!
var searchPredicate: NSPredicate!
var dataFiltered: [Song]? = nil
func updateSearchResultsForSearchController(searchController: UISearchController) {
var searchText = searchController.searchBar.text
searchPredicate = NSPredicate(format: "songName contains[c] %@", searchText)
dataFiltered = self.fetchedResultsController?.fetchedObjects?.filter(){
return self.searchPredicate!.evaluateWithObject($0)
} as! [Song]?
self.tableView.reloadData()
println(searchPredicate)
}
func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
updateSearchResultsForSearchController(searchController)
}
func didDismissSearchController(searchController: UISearchController) {
searchPredicate = nil
dataFiltered = nil
self.tableView.reloadData()
}
override func viewDidLoad() {
super.viewDidLoad()
self.navigationItem.leftBarButtonItem = self.editButtonItem()
fetchedResultsController = NSFetchedResultsController(fetchRequest: returnRequest(), managedObjectContext: context, sectionNameKeyPath: "songName", cacheName: "songName")
fetchedResultsController.delegate = self
fetchedResultsController.performFetch(nil)
searchController = ({
var controllerSearch = UISearchController(searchResultsController: nil)
controllerSearch.delegate = self
controllerSearch.searchBar.delegate = self
controllerSearch.searchBar.sizeToFit()
controllerSearch.definesPresentationContext = false // default false
controllerSearch.hidesNavigationBarDuringPresentation = true
controllerSearch.searchResultsUpdater = self
controllerSearch.dimsBackgroundDuringPresentation = false
self.tableView.tableHeaderView = controllerSearch.searchBar
return controllerSearch
})()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
// #warning Potentially incomplete method implementation.
// Return the number of sections.
if searchPredicate == nil {
return fetchedResultsController?.sections?.count ?? 0
} else {
return 1 ?? 0
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchPredicate == nil {
return fetchedResultsController?.sections?[section].numberOfObjects ?? 0
} else {
return dataFiltered?.count ?? 0
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("songID", forIndexPath: indexPath) as! UITableViewCell
if searchPredicate == nil {
if var dataForCell = fetchedResultsController.objectAtIndexPath(indexPath) as? Song {
cell.textLabel?.text = dataForCell.songName
cell.detailTextLabel?.text = dataForCell.songName
} else {
if var dataFilterForCell = dataFiltered?[indexPath.row] {
cell.textLabel?.text = dataFilterForCell.songName
cell.textLabel?.text = dataFilterForCell.songName
}
}
}
return cell
}
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the specified item to be editable.
return true
}
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
context.deleteObject(fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject)
context.save(nil)
} else if editingStyle == .Insert {
context.insertObject(fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject)
context.save(nil)
}
}
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.searchResultsController as! SongTableVC).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:
tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade)
tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Update:
break
default: break
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
var tableView = UITableView()
if searchPredicate == nil {
tableView = self.tableView
} else {
tableView = (searchController.searchResultsController as! SongTableVC).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: indexPath!) 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.searchResultsController as? SongTableVC)?.tableView.beginUpdates()
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
if searchPredicate == nil {
tableView.endUpdates()
} else {
(searchController.searchResultsController as? SongTableVC)?.tableView.endUpdates()
}
}
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.identifier == "add" {
searchController.active == false
}
}
}
答案 0 :(得分:0)
我找到了问题的解决方案
import UIKit
import Foundation
import CoreData
class SongTableViewController: UITableViewController, UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate, UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating {
// MARK: - var and lets
var appDel = (UIApplication.sharedApplication().delegate as! AppDelegate)
var context = (UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext!
override func viewDidLoad() {
super.viewDidLoad()
fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest(), managedObjectContext: context, sectionNameKeyPath: "nameSong", cacheName: "nameSong")
fetchedResultsController.delegate = self
fetchedResultsController.performFetch(nil)
self.navigationItem.leftBarButtonItem = self.editButtonItem()
searchController = ({
var controllerSearch = UISearchController(searchResultsController: nil)
controllerSearch.delegate = self
controllerSearch.searchBar.delegate = self
controllerSearch.hidesNavigationBarDuringPresentation = true
controllerSearch.definesPresentationContext = false
controllerSearch.dimsBackgroundDuringPresentation = false
controllerSearch.searchBar.sizeToFit()
controllerSearch.searchResultsUpdater = self
self.tableView.tableHeaderView = controllerSearch.searchBar
return controllerSearch
})()
//
println(path)
}
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
searchPredicate = nil
filteredData = nil
self.tableView.reloadData()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
// MARK: - NSFetchedResultsController and its functions
var fetchedResultsController: NSFetchedResultsController!
func fetchRequest() -> NSFetchRequest {
var fetchRequest = NSFetchRequest(entityName: "Song")
var sort = NSSortDescriptor(key: "nameSong", ascending: false)
fetchRequest.fetchBatchSize = 50
fetchRequest.predicate = nil
fetchRequest.sortDescriptors = [sort]
return fetchRequest
}
// MARK: - UISearchController and its functions
var searchController: UISearchController!
var searchPredicate: NSPredicate!
var filteredData: [Song]? = nil
func updateSearchResultsForSearchController(searchController: UISearchController) {
var searchText = searchController.searchBar.text
if searchText != nil {
searchPredicate = NSPredicate(format: "nameSong contains[c] %@", searchText)
filteredData = fetchedResultsController.fetchedObjects!.filter() {
return self.searchPredicate.evaluateWithObject($0)
} as? [Song]
self.tableView.reloadData()
}
}
func searchBar(searchBar: UISearchBar, selectedScopeButtonIndexDidChange selectedScope: Int) {
updateSearchResultsForSearchController(searchController)
}
func didDismissSearchController(searchController: UISearchController) {
searchPredicate = nil
filteredData = nil
self.tableView.reloadData()
}
// MARK: - Files from shared folder
var fileManager = NSFileManager.defaultManager()
var path = NSSearchPathForDirectoriesInDomains(NSSearchPathDirectory.DocumentDirectory, NSSearchPathDomainMask.UserDomainMask, true)
// MARK: - Table view data source
override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
if searchPredicate == nil {
return fetchedResultsController?.sections?.count ?? 0
} else {
return 1 ?? 0
}
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
if searchPredicate == nil {
return fetchedResultsController?.sections?[section].numberOfObjects ?? 0
} else {
return filteredData?.count ?? 0
}
}
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("songID", forIndexPath: indexPath) as! UITableViewCell
if searchPredicate == nil {
if var dataForCell = fetchedResultsController?.objectAtIndexPath(indexPath) as? Song {
cell.textLabel?.text = dataForCell.nameSong
}
} else {
if var filteredSearch = filteredData?[indexPath.row] {
cell.textLabel?.text = filteredSearch.nameSong
}
}
return cell
}
// Override to support conditional editing of the table view.
override func tableView(tableView: UITableView, canEditRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the specified item to be editable.
return true
}
// Override to support editing the table view.
override func tableView(tableView: UITableView, commitEditingStyle editingStyle: UITableViewCellEditingStyle, forRowAtIndexPath indexPath: NSIndexPath) {
if editingStyle == .Delete {
context.deleteObject(fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject)
context.save(nil)
} else if editingStyle == .Insert {
context.insertObject(fetchedResultsController.objectAtIndexPath(indexPath) as! NSManagedObject)
context.save(nil)
}
}
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:
tableView.deleteSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade)
tableView.insertSections(NSIndexSet(index: sectionIndex), withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Update:
break
default: break
}
}
func controller(controller: NSFetchedResultsController, didChangeObject anObject: AnyObject, atIndexPath indexPath: NSIndexPath?, forChangeType type: NSFetchedResultsChangeType, newIndexPath: NSIndexPath?) {
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: indexPath!) as [AnyObject], withRowAnimation: UITableViewRowAnimation.Fade)
break
case NSFetchedResultsChangeType.Update:
tableView.cellForRowAtIndexPath(indexPath!)
break
default: break
}
}
func controllerDidChangeContent(controller: NSFetchedResultsController) {
tableView.endUpdates()
}
func controllerWillChangeContent(controller: NSFetchedResultsController) {
tableView.beginUpdates()
}
/*
// Override to support rearranging the table view.
override func tableView(tableView: UITableView, moveRowAtIndexPath fromIndexPath: NSIndexPath, toIndexPath: NSIndexPath) {
}
*/
// Override to support conditional rearranging of the table view.
override func tableView(tableView: UITableView, canMoveRowAtIndexPath indexPath: NSIndexPath) -> Bool {
// Return NO if you do not want the item to be re-orderable.
return true
}
/*
// MARK: - Navigation
// In a storyboard-based application, you will often want to do a little preparation before navigation
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
// Get the new view controller using [segue destinationViewController].
// Pass the selected object to the new view controller.
}
*/
}