2017-07-30 77 views
0

我創建了一個聯繫人應用程序,到目前爲止,我已經成功設法將項目保存到我的tableview。我有一個搜索欄,我想通過名字過濾掉我的單元格,我知道,因爲我在使用核心數據,我必須使用fetchResultsController和NSPredicate。我無法把這些東西全部弄清楚,也許有人可以幫助我?如何過濾我的核心數據中有對象的tableview?

另外這裏是我的核心數據實體,以防萬一。

實體:聯繫

屬性:

  • 名字,字符串
  • 姓氏,字符串
  • 出生日期,字符串
  • phoneNumber的,字符串
  • 郵政編碼,字符串

我知道一些代碼可能不完整,但我只需要在何處採取這一方向。我只是想讓用戶輸入一個名字,它會按名字過濾單元格。讓我知道你是否需要更多信息。

現在,這裏是我ContactsTableVC代碼:

import UIKit 
import CoreData 

class ContactsTableVC: UITableViewController, UISearchBarDelegate, NSFetchedResultsControllerDelegate { 

    @IBOutlet weak var searchBar: UISearchBar! 

    var isFiltered: Bool = false 

//Holds the core data model 
    var persons: [Person] = [] 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     searchBar.delegate = self 

     self.tableView.separatorStyle = UITableViewCellSeparatorStyle.none 
     self.tableView.backgroundColor = UIColor(red: 240/255.0, green: 240/255.0, blue: 240/255.0, alpha: 1.0) 

     fetch() 
     self.tableView.reloadData() 
    } 

    func getContext() -> NSManagedObjectContext { 
     let appDelegate = UIApplication.shared.delegate as! AppDelegate 
     return appDelegate.persistentContainer.viewContext 
    } 

    // MARK: - Searchbar 
    //add fetchrequest to did ebgin editing 
    func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) { 

    } 

    func searchBarTextDidEndEditing(_ searchBar: UISearchBar) { 
     if(searchBar.text == "") { 
      isFiltered = false 
     } else { 
      isFiltered = true 
     } 
    } 

    func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 
     filter(text: searchText) 
    } 

    // MARK: - Fetchresults controller/filtering data 

    func filter(text: String) { 
     //Create fetch request 
     let fetchRequest = NSFetchRequest<Person>() 

//  guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return }   replaced with getcontext 
//  let managedObjectContext = appDelegate.persistentContainer.viewContext 

     let entity = NSEntityDescription.entity(forEntityName: "Contact", in: getContext()) 
     fetchRequest.entity = entity 

     let sortDescriptor = NSSortDescriptor(key: "firstName", ascending: false) 
     let sortDescriptors: [Any] = [sortDescriptor] 
     fetchRequest.sortDescriptors = sortDescriptors as? [NSSortDescriptor] ?? [NSSortDescriptor]() 

     if(text.characters.count > 0) { 
      let predicate = NSPredicate(format: "(firstName CONTAINS[c] %@)", text) 
      fetchRequest.predicate = predicate 
     } 

     let loadedEntities: [Person]? = try? getContext().fetch(fetchRequest) 
     filteredContacts = [Any](arrayLiteral: loadedEntities) as! [Person] 
     self.tableView.reloadData() 
    } 

    // MARK: - Data Source 
    func fetch() { 
     guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return } 
     let managedObjectContext = appDelegate.persistentContainer.viewContext 
     let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName:"Contact") 
     do { 
      persons = try managedObjectContext.fetch(fetchRequest) as! [Person] //NSManagedObject 
     } catch let error as NSError { 
      print("Could not fetch. \(error)") 
     } 
    } 

    func save(firstName: String, lastName: String, dob: String, phoneNumber: String, zipCode: String) { 
     guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return } 
     let managedObjectContext = appDelegate.persistentContainer.viewContext 
     guard let entity = NSEntityDescription.entity(forEntityName:"Contact", in: managedObjectContext) else { return } 
     let person = NSManagedObject(entity: entity, insertInto: managedObjectContext) 
     person.setValue(firstName, forKey: "firstName") 
     person.setValue(lastName, forKey: "lastName") 
     person.setValue(dob, forKey: "dateOfBirth") 
     person.setValue(phoneNumber, forKey: "phoneNumber") 
     person.setValue(zipCode, forKey: "zipCode") 
     do { 
      try managedObjectContext.save() 
      self.persons.append(person as! Person) //previously just contact, no casting! 
     } catch let error as NSError { 
      print("Couldn't save. \(error)") 
     } 
    } 

    func update(indexPath: IndexPath, firstName: String, lastName: String, dob: String, phoneNumber: String, zipCode: String) { 
     guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return } 
     let managedObjectContext = appDelegate.persistentContainer.viewContext 
     let contact = persons[indexPath.row] 
     contact.setValue(firstName, forKey: "firstName") 
     contact.setValue(lastName, forKey: "lastName") 
     contact.setValue(dob, forKey: "dateOfBirth") 
     contact.setValue(phoneNumber, forKey: "phoneNumber") 
     contact.setValue(zipCode, forKey: "zipCode") 
     do { 
      try managedObjectContext.save() 
      persons[indexPath.row] = contact 
     } catch let error as NSError { 
      print("Couldn't update. \(error)") 
     } 
    } 

    func delete(_ contact: NSManagedObject, at indexPath: IndexPath) { 
     guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else { return } 
     let managedObjectContext = appDelegate.persistentContainer.viewContext 
     managedObjectContext.delete(contact) 
     persons.remove(at: indexPath.row) 

     //Always remember to save after deleting, updates Core Data 
     do { 
      try managedObjectContext.save() 
     } catch { 
      print("Something went wrong \(error.localizedDescription)") 
     } 
    } 

    // MARK: - Table View Setup 
    override func numberOfSections(in tableView: UITableView) -> Int { 
     return 1 
    } 

    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
     return persons.count 
    } 


    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "ContactCell", for: indexPath) as? PersonsCell 

     let person = persons[indexPath.row] 

     cell?.firstName?.text = person.value(forKey:"firstName") as? String 
     cell?.lastName?.text = person.value(forKey:"lastName") as? String 
     cell?.dob?.text = person.value(forKey:"dateOfBirth") as? String 
     cell?.phoneNumber?.text = person.value(forKey:"phoneNumber") as? String 
     cell?.zipCode?.text = person.value(forKey:"zipCode") as? String 

     return cell! 
    } 

    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { 
     return 75 
    } 

    // Override to support conditional editing of the table view. 
    override func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool { 
     return true 
    } 

    // MARK: - Navigation 
    @IBAction func unwindToContactsList(segue:UIStoryboardSegue) { 
     if let viewController = segue.source as? AddContactVC { 
      guard let _firstName: String = viewController.firstNameLbl.text, 
       let _lastName: String = viewController.lastNameLbl.text, 
       let _dob: String = viewController.dateOfBirthLbl.text, 
       let _phoneNumber: String = viewController.phoneNumberLbl.text, 
       let _zipCode: String = viewController.zipCodeLbl.text 
       else { return } 
      if _firstName != "" && _lastName != "" && _dob != "" && _phoneNumber != "" && _zipCode != "" { 
       if let indexPath = viewController.indexPathForContact { 
        update(indexPath: indexPath, firstName: _firstName, lastName: _lastName, dob: _dob, phoneNumber: _phoneNumber, zipCode: _zipCode) 
        print("Any updates?") 
       } else { 
        save(firstName: _firstName, lastName: _lastName, dob: _dob, phoneNumber: _phoneNumber, zipCode: _zipCode) 
        print("added to tableview") //this runs twice for some reason... 
       } 
      } 
      tableView.reloadData() 
     } else if let viewController = segue.source as? EditContactVC { 
      if viewController.isDeleted { 
       guard let indexPath: IndexPath = viewController.indexPath else { return } 
       let person = persons[indexPath.row] 
       delete(person, at: indexPath) 
       tableView.reloadData() 
      } 
     } 
    } 
} 

回答

1

這裏是一個示例代碼NSFetchedResultsController來實現自己的目標。我省略了一些不相關的代碼。

相關問題