私は単純なTodoアプリケーションを持っています。メイン画面では、利用可能なタスクのリストを表示します。各セルは、カテゴリの色、カテゴリ名、タイトル、日付のための小さなUIViewを表示します。最初の起動時にはすべてのデータがCorrenctを表示しますが、そのうちの1つを選択して別のカテゴリの色でカテゴリを変更し、CoreDataの変更を保存すると、モーダルビュー(データを更新する場所)が消え、NSFetchedResultControllerがnewデータをフェッチしてtableViewデータは変更されますが、更新前と同じように色が変わりません。注:ウィンドウが消えると、最初にセルが更新されたときに正しい色が表示され、2番目のセルが古いものに変更された後に表示されます。私は、正しい、新しいデータがCoreDataからフェッチされ、すべてが正しくレンダリングする必要がありますが、UIViewの背景色が間違っているアプリ、デバッガのショーをデバッグしました。CoreDataからフェッチした後のセルのUIViewが間違った色を表示する
これは私のセルのコードです:
@IBOutlet weak var title: UILabel!
@IBOutlet weak var category: UILabel!
@IBOutlet weak var date: UILabel!
@IBOutlet weak var progress: UILabel!
@IBOutlet weak var categoryColorView: UIView!
override func awakeFromNib() {
super.awakeFromNib()
}
var viewModel: TaskCellViewModel! {
didSet {
title.text = viewModel.title
category.text = viewModel.categoryName
date.text = convert()
progress.text = viewModel.isDone ? "Done" : "In Progress"
progress.textColor = viewModel.isDone ? UIColor.green : UIColor.red
categoryColorView.backgroundColor = Constants.colors[viewModel.categoryColor]!.color
}
}
と、これは細胞である:
EDIT:: これはNewTaskViewModelから呼び出される/更新方法、保存され
func save(completion: @escaping (AppResult<Task>) -> Void) {
let context = CustomContext.shared.getContext
do {
if _task.id != "" {
let taskFetchRequest: NSFetchRequest<TaskEntity> = TaskEntity.fetchRequest()
taskFetchRequest.predicate = NSPredicate(format: "id == %@", _task.id)
let taskEntity = try context.fetch(taskFetchRequest).first!
taskEntity.title = task.title
taskEntity.date = task.date as NSDate?
taskEntity.content = task.content
taskEntity.isDone = task.isDone
let categoryFetchRequest: NSFetchRequest<CategoryEntity> = CategoryEntity.fetchRequest()
categoryFetchRequest.predicate = NSPredicate(format: "name == %@", _task.category.name)
taskEntity.category = try context.fetch(categoryFetchRequest).first!
} else {
let taskEntity = TaskEntity(context: context)
taskEntity.id = UUID().uuidString
taskEntity.title = task.title
taskEntity.date = task.date as NSDate?
taskEntity.content = task.content
taskEntity.isDone = task.isDone
let categoryFetchRequest: NSFetchRequest<CategoryEntity> = CategoryEntity.fetchRequest()
categoryFetchRequest.predicate = NSPredicate(format: "name == %@", _task.category.name)
taskEntity.category = try context.fetch(categoryFetchRequest).first!
}
try context.save()
completion(.success(task))
} catch {
completion(.error(error.localizedDescription))
}
}
これはNewTaskViewController(モーダルビュー)から/更新を救うの呼び出しです:
@IBAction func save(_ sender: UIBarButtonItem) {
switch viewModel.validation() {
case .success(_):
viewModel.save { result in
switch result {
case .success(_):
DispatchQueue.main.async { [unowned self] in
self.dismiss(animated: true, completion: nil)
}
case .error(let error):
DispatchQueue.main.async { [unowned self] in
self.errorAlert(withMessage: error)
}
}
}
case .error(let errorMsg):
DispatchQueue.main.async { [unowned self] in
self.errorAlert(withMessage: errorMsg)
}
}
}
のtableViewのcellForRowAt:
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: Constants.taskCell, for: indexPath) as! TaskCell
cell.viewModel = viewModel.getTaskCell(indexPath: indexPath)
return cell
}
getTaskCell:
func getTaskCell(indexPath: IndexPath) -> TaskCellViewModel {
let taskEntity = fetchedResultsController.object(at: indexPath)
return TaskCellViewModel(withTask: taskEntity.convertToModel())
}
taskEntity.convertToModel()
@NSManaged public var id: String?
@NSManaged public var content: String?
@NSManaged public var date: NSDate?
@NSManaged public var isDone: Bool
@NSManaged public var title: String?
@NSManaged public var category: CategoryEntity?
func convertToModel() -> Task {
var task = Task()
task.id = self.id!
task.title = self.title!
task.content = self.content!
task.isDone = self.isDone
task.date = self.date! as Date
task.category.name = self.category!.name!
task.category.color = Constants.colors[self.category!.color!]!
return task
}
とNSFetchedResultControllerDelegates年代:
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.beginUpdates()
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
tableView.endUpdates()
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
if let indexPath = newIndexPath {
tableView.insertRows(at: [indexPath], with: .fade)
}
break
case .update:
if let indexPath = indexPath {
let cell = tableView.cellForRow(at: indexPath) as! TaskCell
cell.viewModel = viewModel.getTaskCell(indexPath: indexPath)
}
break
case .delete:
if let indexPath = indexPath {
tableView.deleteRows(at: [indexPath], with: .fade)
}
break
default:
break
}
}
あなたが書いたこれらの行のコードをもっと更新してもいいですか?そのうちの1つを選択して別のカテゴリの色でカテゴリを変更し、CoreDataの変更を保存すると、(データを更新する)モーダルビューが消え、NSFetchedResultController新しいデータを取得してtableViewを読み込み、すべてのデータが変更されますが、更新前の色だけが残っています。 –
@ArunKumar私は投稿を編集しました –