FRC填充TableView但FetchedResultsControllerDelegate方法不起作用

时间:2017-07-30 09:14:18

标签: swift core-data nsfetchedresultscontroller

我有一个名为 ScorecardViewController 的视图控制器,其中包含UITableView,名为 HolesTable ,已正确填充通过FetchedResultsController

但是,当用户编辑任何数据时,不会调用任何FRC delegate方法 - 即我在每个FRC delegate方法上设置了断点,并且没有触发任何数据。

ScorecardViewController HolesTable 的委托,并为其实现必要的方法集。此外, HolesTable ,将其数据源和delegate设置为IB ScorecardViewController

对于上下文,在应用程序的其他位置,我有一个几乎相同的设置, 正常工作。我有一个视图控制器, CourseViewController ,它托管了UITableView ScorecardTable ,它有一个与之链接的FRC。

ScorecardTable 从FRC正确填充,并且所有FRC delegate方法都按预期触发。

经过对我的代码和在线研究的广泛审核后,我得出的结论是,我错过了将 HoleTable 连接到FRC delegate的某个步骤,但我可以'找出发生这种情况的地方,因为我对两个VC的检查没有显示任何明显的结果。

我还有什么可能错过的吗?我可以发布哪些代码有助于确定问题所在?

谢谢!

- 更新1

因此定义了FRC:

fileprivate lazy var fetchedResultsController: NSFetchedResultsController<Hole> = {
// Create Fetch Request
let fetchRequest: NSFetchRequest<Hole> = Hole.fetchRequest()

// Configure Fetch Request
self.teeColourString = self.scorecard?.value(forKey: "teeColour") as! String?
fetchRequest.predicate = NSPredicate(format: "%K == %@ AND %K == %@", "appearsOn.offeredAt.name", self.courseName!, "appearsOn.teeColour", self.teeColourString!)

fetchRequest.sortDescriptors = [NSSortDescriptor(key: "holeNumber", ascending: true)]

// Create Fetched Results Controller
let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.coreDataManager.mainManagedObjectContext, sectionNameKeyPath: nil, cacheName: nil)

// Configure Fetched Results Controller
fetchedResultsController.delegate = self

return fetchedResultsController

}()

FRC效果很好,它会填充已连接的tableView对象HoleTable

Hole表包含三个整数列HoleNumParStrokeIndex。我有一个自定义单元格HoleTableViewCell,其中这些值显示在HoleTable

ParStrokeIndex可以通过HoleTable的实例进行更新,用户可以直接编辑单元格。 “HoleTableViewCell”的代码是:

class HoleTableViewCell: UITableViewCell, UITextFieldDelegate {

    @IBOutlet weak var holeNumLabel: UILabel!
    @IBOutlet weak var SIField: UITextField!
    @IBOutlet weak var parField: UITextField!

    static let reuseIdentifier = "HoleTableViewCell"

    func textFieldDidBeginEditing(_ textField: UITextField) {
        print("Editing started")
    }

    func textFieldDidEndEditing(_ textField: UITextField) {
        if textField.tag == 4 {
            //ParField has been edited
            print("Par is now " + textField.text!)
        } else if textField.tag == 5 {
            // SIField has been edited
            print("SI is now " + textField.text!)
        }
    }
    override func awakeFromNib() {
        super.awakeFromNib()

        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
        SIField.delegate = self
        SIField.tag = 4
        parField.delegate = self
        parField.tag = 5
    }
}

在运行时,正如我所料,编辑到文本字段SIFieldparField会触发textFieldDidBeginEditingtextFieldDidEndEditing

触发FRC委托方法不会发生什么。这些是在UITableView的类中定义的ScorecardViewController,其中FetchedResultsControllerDelegate协议方法已设置。

- 更新2

经过进一步调查后,我认为FRC委托方法未触发的原因是因为FRC后面的托管对象上下文没有发生更新。

我将进一步研究这一点,看看是否有一种直接的方法来实现这一目标。

1 个答案:

答案 0 :(得分:0)

事实证明这个解决方案很简单,但需要一些脑细胞来解决。

缺少的部分是我需要将对象的引用从HolesTable TableView传递给`HoleTableViewCell&#39;单元格,因此我在单元格方法中的编辑触发了FRC委托方法。

新课程&#39; HoleTableViewCell&#39;定义如下:

import UIKit
import CoreData

class HoleTableViewCell: UITableViewCell, UITextFieldDelegate {

    @IBOutlet weak var holeNumLabel: UILabel!
    @IBOutlet weak var SIField: UITextField!
    @IBOutlet weak var parField: UITextField!

    var hole: Hole?

    static let reuseIdentifier = "HoleTableViewCell"

    func textFieldDidBeginEditing(_ textField: UITextField) {
        print("Editing started")
    }

    // This will need beefing up to enforce rules for Par and SI
    func textFieldDidEndEditing(_ textField: UITextField) {
        if textField.tag == 4 || textField.tag == 5 {
            //ParField has been edited

            //Prepare the Hole record for sending back to calling controller
            hole?.setValue(Int(parField.text!), forKeyPath: "par")
            hole?.setValue(Int(SIField.text!), forKey: "strokeIndex")
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()

        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
        SIField.delegate = self
        SIField.tag = 4
        parField.delegate = self
        parField.tag = 5
    }
}

并且,在保存单元格的UITableView的类定义中,需要以下内容:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

guard let cell = tableView.dequeueReusableCell(withIdentifier: HoleTableViewCell.reuseIdentifier, for: indexPath) as? HoleTableViewCell else {
    fatalError("Unexpected Index Path")
}

// Fetch Holes
let hole = fetchedResultsController.object(at: indexPath)


// Pass the hole to the cell instance so edits in situ will trigger FRC delegate methods
cell.hole = hole

return cell

}