我必须错过一些简单的东西,但无法确定它是什么。当然,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并立即再次加载它,屏幕正确显示内容。只希望它做到了而不必“回家并返回”。
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
}
}
}