fetchRequest之后,CoreData值更改后,CustomCell内容未更新

时间:2018-07-09 03:44:12

标签: ios uitableview core-data nsfetchrequest custom-cell

我必须错过一些简单的东西,但无法确定它是什么。当然,BASIC和FORTRAN似乎容易得多……只是不像这些东西那么酷。

App用于基于谓词显示和排序存储在CoreData中的抽认卡。选择修改谓词的选项后,将显示一个UITableView,以缩写形式列出满足条件的卡片。在UITableView中选择具有相同谓词设置的第二行控制器选择卡片行,只能显示更多内容,并且“技能级别”可以通过CoreData修改并保存到此第二行控制器上。根据fetchRequest谓词,卡可能不再符合条件,可能会从后续的fetchRequest中排除。这一切似乎都能正常运行。

选择“返回”将通过第二步从第二个返回到第一个UITableView控制器。此时,再次执行fetchRequest和tableview.reloadData()。返回时,抽认卡会根据任何更改以正确的顺序排序。不再满足谓词条件的抽认卡已从表中正确排除。

问题是这样的-自定义单元格内容不反映所做的任何更改(从tableView打印时,星形图形不变,技能水平的数值也不变)。 TableView可以正确排序,并且不包含不应包含的项目,这似乎表明已保存更新的信息,并且tableView已将其考虑在内。 TableView只是不在屏幕上显示。

如果我再次选择“返回”,则返回“主页”或初始viewController并立即重新选择tableView正确显示。

我尝试将tableView.reloadData()放置在各个位置(带有和不带有.self),将获取和重新加载移入和移出DispatchQueue.main.async。尝试将自定义单元格中的控件替换为图像,但这也不起作用。在堆栈溢出或互联网上的其他地方似乎找不到任何类似的东西。

任何帮助将不胜感激。

自定义单元格:

import UIKit
class CardsTableViewCell: UITableViewCell {

    // MARK: Properties
    @IBOutlet weak var questionLabel: UILabel!
    @IBOutlet weak var difficultyImageView: UIImageView!
    @IBOutlet weak var knowItControl: KnowItControl!

    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
    }
}

UnwindFromSegue:

@IBAction func unwindToCardsTableViewController(sender: UIStoryboardSegue) {   
        DispatchQueue.main.async{
            // RELOAD THE FLASHCARDS FOR TABLEVIEW
            do {
                try self.fetchedResultsController.performFetch()
            } catch let error as NSError {
                print("Fetching error: \(error), \(error.userInfo)")
            }
            print("\n UNWIND - About to reload table")
                self.tableView.reloadData()
        }
        print("UNWIND SEGUE from DetailedCardsView")
        // Considered giving up and just dumping back to Main Screen.
        // dismiss(animated: true, completion: nil)
    }

使用tableViewController中的扩展程序组装tableView

// MARK: - ConfigureCardsTableViewCell
extension CardsTableViewController {

    func configure(cell: UITableViewCell, for indexPath: IndexPath) {
       guard let cell = cell as? CardsTableViewCell else { return }

        let flashCards = fetchedResultsController.object(at: indexPath)
        cell.knowItControl.rating = Int(flashCards.cardKnowIt)
        cell.questionLabel.text = flashCards.cardQuestion

        // * * *  ASSIGN THE IMAGE BASED ON THE levelDifficulty * * *
        switch flashCards.levelDifficulty {
        case "e"?:
            cell.difficultyImageView.image = UIImage(named: "activeLetterE")
        case "g"?:
            cell.difficultyImageView.image = UIImage(named: "activeLetterG")
        case "m"?:
            cell.difficultyImageView.image = UIImage(named: "activeLetterM")
        default:
            cell.difficultyImageView.image = UIImage(named: "activeLetterE")
        }
        //  *************************  END OF ASSIGN IMAGE ****************************************
        print("assembling cell \(indexPath.row) *** knowIt - \(Int(flashCards.cardKnowIt))")  // Observe what is going on, see if value was updated (it's not).
        }
}


// * * * *    T A B L E V I E W     D A T A S O U R C E  * * * *
// MARK: - UITableViewDataSource
extension CardsTableViewController: UITableViewDataSource {

    // * * *   C O N F I G U R E    T H E   C E L L   V I A    A   C A L L   * * *
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "cardCellReuse", for: indexPath)
        configure(cell: cell, for: indexPath)
        print("   Configuring cell \(indexPath)")   // Observe what is going on.
        return cell
        }
 // general tableView functions for number of rows, sections, etc.   
}

viewController还包含通用的NSFetchedResultsControllerDelegate,我相信它与我遇到的所有示例都完全匹配。

此处显示的屏幕截图。 1-从“主页”页面的第一个tableView的初始加载正确显示了内容。 2-设置到第二个tableView,在那里进行更改并将其保存到CoreData。 3-使用展开功能返回到第一个tableView。单元格已正确排序,但不包含更新的值。 4-通过“后退”左1st tableView并立即再次加载它,屏幕正确显示内容。只希望它做到了而不必“回家并返回”。 1st tableView displaying cards meeting criteria

2nd tableView after segue from 1st, changing the Skill Level & saving it

Returned to 1st tableView where items are properly sorted, but cells unchanged.

Exit 1st tableView via "Back" & re-load. All appears as it should.

NSFetched Results Controller Delegate:

// MARK: - NSFetchedResultsControllerDelegate
extension CardsTableViewController: NSFetchedResultsControllerDelegate {
    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.beginUpdates()
        print("\n **** tableView.beganUpdates called")
    }

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

        switch type {
        case .insert:
            tableView.insertRows(at: [newIndexPath!], with: .automatic)
        case .delete:
            tableView.deleteRows(at: [indexPath!], with: .automatic)
        case .update:
            let cell = tableView.cellForRow(at: indexPath!) as! CardsTableViewCell
            configure(cell: cell, for: indexPath!)
            print("case .update was called.")
        case .move:
            tableView.deleteRows(at: [indexPath!], with: .automatic)
            tableView.insertRows(at: [newIndexPath!], with: .automatic)
        }
    }

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        tableView.endUpdates()
        print("\n **** tableView.endUpdates called")
    }

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {

        let indexSet = IndexSet(integer: sectionIndex)

        switch type {
        case .insert:
            tableView.insertSections(indexSet, with: .automatic)
        case .delete:
            tableView.deleteSections(indexSet, with: .automatic)
        default: break
        }
    }
}

0 个答案:

没有答案