0

Я новичок в разработке iOS и в своем втором приложении с Swift. Я не могу включить SearchBar & Показать поиск в моем контроллере табличного представления.SearchBar & Display в виде таблицы с Coredata с использованием Swift?

В моем приложении 2 вида. Первый вид создает массив плодов. Вывод первого вида: [Apple, Orange, Banana, Pears]. Затем [Гранат, Груши, Арбуз, Мускмелон] и так далее. Один массив за раз.

Каждый массив фруктов хранится в данных ядра с использованием NSFetchedResultsController для отображения в контроллере tableview. Мои CoreData расположение:

import UIKit 
import CoreData 

@objc(Fruits) 

class Fruits: NSManagedObject { 
    @NSManaged var date: String 
    @NSManaged var fruit: String 
} 

My Second View отображает список фруктов. Теперь я добавил панель поиска & Дисплей сверху на столе. Но я не могу заставить его работать.

Используемые протоколы:

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-кодировании?

Любая помощь по концепции, которую я, возможно, пропустил где-то здесь, будет оценен по достоинству! Благодарю.

Update: Дэниел Эггерт предложил я пытаюсь использовать предикат для функциональности поиска контроллера, но Сказуемое всегда дает ноль. Что мне не хватает ???

Переменные, объявленная в классе:

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, как ее обрабатывать? – Satyam

ответ

0

Вы хотите установить предикат на вас извлеченный контроллере результатов.

После того как вы изменили запрос на выборку на выбранном контроллере результатов, вам нужно позвонить performFetch(), чтобы он обновил свои данные. Затем вызовите reloadData() на вид таблицы.

Текстовый поиск для нетривиальных примеров может быть сложным, но, тем не менее, из-за взаимодействия языков, локалей и Юникода. Я бы порекомендовал Текст глава моей книги: https://www.objc.io/books/core-data/

+0

Даниил, пожалуйста, предложите, правильный ли подход, который я принял. глава _Text_ в вашей книге доступна при покупке. –

+0

красивая книга, купленная и мне она нравится. Наконец, некоторые примеры Swift/iOS и практические подходы. 10/10 рекомендовал бы – Jerland2

0

Если вы хотите реализовать поисковый tableView? Вы должны использовать метод протокола UISearchResultsUpdating вместо метода протокола UISearchBarDelegate под названием searchBar:textDidChange.Вы можете использовать метод searchBar:textDidChange, когда метод UISearchResultsUpdating не доступен! Оба класса полезны и эффективны. И легко реализовать