swift - 使用 fetchcontroller 从 TableView 单元格中获取对象?

标签 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)")
            }
        }
    }

}

最佳答案

首先在当前的 VC 中创建一个本地 var 并在 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
         }
     }
}

关于swift - 使用 fetchcontroller 从 TableView 单元格中获取对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41062342/

相关文章:

swift - 相互依赖的 RxSwift 链接请求

objective-c - Objective-c:如何存储大量数据(iOS RSS应用程序)

reactjs - 当尝试使用获取对响应应用程序在Cypress IO(JS)中 stub 请求时,请求仍会调用服务器

javascript - React Setstate 在 JSON 化后使我的状态项未定义

ios - 如何将 3 个 View Controller 嵌入到 1 个 View Controller 中?

swift - 核心数据 : error: Failed to call designated initializer on NSManagedObject custom class

ios - Azure 移动服务脱机数据同步 - pullWithQuery 错误

php - 如何只显示不为空的行

ios - 多行的 UICollectionView

ios - Swift Core Data - 如何更新所有子实体的属性?