使用fetchcontroller从tableview单元格中获取对象?

时间:2016-12-09 14:12:05

标签: swift core-data fetch

我希望用户能够单击表中的单元格并检索该索引路径中的任何对象并将其设置为变量,以便我可以将其拉到下一个VC。

这是如何实现的?我的逻辑是使用类似的东西:

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
   if segue.identifier == "loadTodaysRoutine" { 
      setRoutine = fetchedResultsController.fetchedobjects[indexPath.row]
      if let todaysRoutineController = segue.destination as? RoutineController {
                todaysRoutineController.routineObject = setRoutine
      }

我认为这会使setRoutine点击索引补丁,然后我可以通过segue将它发送到另一个VC,但我觉得我错过了一些步骤,因为它不起作用!

感谢您填补我理解中的空白的任何帮助

根据要求更新整个VC

import Foundation
import UIKit
import CoreData

class YourWorkoutsController: UIViewController, UITableViewDataSource, UITableViewDelegate, NSFetchedResultsControllerDelegate {

    // MARK: - DECLARATIONS

    private let persistentContainer = NSPersistentContainer(name: "Lift")
    var managedObjectContext: NSManagedObjectContext?

    fileprivate var setRoutine: NSManagedObject?

    @IBAction func unwindToTemplates(segue: UIStoryboardSegue) {}
    @IBOutlet weak var workoutTemplateTable: UITableView!
    @IBOutlet weak var createWorkoutLabel: UILabel!
    @IBOutlet weak var nameLabel: UILabel!

    // MARK: - ACTIONS

    @IBAction func cancelWorkoutSelection(_ sender: Any) {
        self.performSegue(withIdentifier: "unwindToRoutineWithSegue", sender: self)
    }

    // MARK: - VIEWDIDLOAD

    override func viewDidLoad() {
        super.viewDidLoad()
        setupView()
        workoutTemplateTable.delegate = self
        workoutTemplateTable.dataSource = self

        view.backgroundColor = (UIColor.customBackgroundGraphite())

        persistentContainer.loadPersistentStores { (persistentStoreDescription, error) in
            if let error = error {
                print("Unable to Load Persistent Store")
                print("\(error), \(error.localizedDescription)")

            } else {
                self.setupView()

                do {
                    try self.fetchedResultsController.performFetch()
                } catch {
                    let fetchError = error as NSError
                    print("Unable to Perform Fetch Request")
                    print("\(fetchError), \(fetchError.localizedDescription)")
                }

                self.updateView()
            }
        }
    }

    // MARK: - VIEWWILLAPPEAR

    override func viewWillAppear(_ animated: Bool) {

        do {
            try self.fetchedResultsController.performFetch()
        } catch {
            let fetchError = error as NSError
            print("Unable to Perform Fetch Request")
            print("\(fetchError), \(fetchError.localizedDescription)")
        }
        self.workoutTemplateTable.reloadData()
    }


    // MARK: - TABLE SETUP

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        guard let userRoutine = fetchedResultsController.fetchedObjects else { return 0 }
        return userRoutine.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath)

        cell.backgroundColor = UIColor.customBackgroundGraphite()
        cell.textLabel?.textColor = UIColor.white

        let userRoutine = fetchedResultsController.object(at: indexPath)
        cell.textLabel?.text = userRoutine.name
        return cell
    }

    // MARK: - TABLE UPDATING COMPONENTS

    private func setupView() {
        setupMessageLabel()
        updateView()
    }

    private func setupMessageLabel() {
        createWorkoutLabel.text = "You Don't Have Any Workouts Yet\n Tap + To Create A New Workout"
    }

    fileprivate func updateView() {
        var hasUserRoutines = false
        if let UserRoutine = fetchedResultsController.fetchedObjects {
            hasUserRoutines = UserRoutine.count > 0
        }
        workoutTemplateTable.isHidden = !hasUserRoutines
        createWorkoutLabel.isHidden = hasUserRoutines

    }

    // MARK: - COREDATA FETCH

    fileprivate lazy var fetchedResultsController: NSFetchedResultsController<UserRoutine> = {

        // Create Fetch Request
        let fetchRequest: NSFetchRequest<UserRoutine> = UserRoutine.fetchRequest()
        // Configure Fetch Request
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "name", ascending: true)]
        // Create Fetched Results Controller
        let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil)
        // Configure Fetched Results Controller
        fetchedResultsController.delegate = self
        return fetchedResultsController
    }()

    // MARK: - ADDING NEW ROUTINE TO THE VC / PUSHING ROUTINE TO TODAYSROUTINE VC

    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        self.setRoutine = fetchedResultsController.fetchedObjects[indexPath.row]
    }

    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        if segue.identifier == "addNewRoutineSegue" {
            if let destinationViewController = segue.destination as? WorkoutDesignerController {
                // Configure View Controller
                destinationViewController.managedObjectContext = persistentContainer.viewContext
            }
        }

        if segue.identifier == "loadTodaysRoutine" {

            if let todaysRoutineController = segue.destination as? RoutineController {
                todaysRoutineController.routineObject = self.setRoutine
            }
        }
    }



    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        workoutTemplateTable.beginUpdates()
    }

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        workoutTemplateTable.endUpdates()
        updateView()
    }

    // MARK: - ADDING TABLE ROW

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
        switch (type) {
        case .insert:
            if let indexPath = newIndexPath {
                workoutTemplateTable.insertRows(at: [indexPath], with: .fade)
            }
            break;
        case .delete:
            if let indexPath = indexPath {
                workoutTemplateTable.deleteRows(at: [indexPath], with: .fade)
            }
            break;
        default:
            print("...")
        }
    }

    // MARK: - DELETING TABLE ROW

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if editingStyle == .delete {
            //fetch exercise
            let UserRoutine = fetchedResultsController.managedObjectContext
            //delete exercise
            UserRoutine.delete(fetchedResultsController.object(at: indexPath))
            //save exercise persistence
            do {
                try UserRoutine.save()
            } catch {
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }
    }

}

1 个答案:

答案 0 :(得分:0)

首先在当前var中创建一个本地VC,然后在didSelectRow中为其分配值:

fileprivate var setRoutine: Any?
.....

func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
       if let routine = fetchedResultsController.fetchedObjects[indexPath.row] {
        self.setRoutine = routine
    }
} 

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
     if segue.identifier == "loadTodaysRoutine" { 
         if let todaysRoutineController = segue.destination as? RoutineController {
               todaysRoutineController.routineObject = self.setRoutine
         }
     }
}