[英]SwiftUI Core Data list does not sorted, close and reopen child view when i insert item
[英]Collection view does not display item when inserting item to DB (Core data)
我有一個集合視圖,當我添加游戲時應該顯示游戲。 在AddGameController
上,我添加了一個游戲並使用核心數據保存它。 當 AddGameVC 關閉時,welcomeVC 會顯示。 但是,當從AddGameController
插入游戲時,集合視圖不會更新,除非我殺死應用程序以便在視圖加載時獲取 object。 我怎樣才能讓它工作?
作為解決方案,我在插入時在didChange
方法中添加了此代碼collectionView.reloadItems(at: [newIndexPath!])
,並嘗試在關閉AddGameController
之前重新加載數據源,但它沒有使其工作。
更新:當有插入時,我得到:線程 1:異常:“嘗試將項目 0 插入第 0 節,但更新后第 0 節中只有 0 個項目”
Class AddGameController: UITableViewController {
func textfieldValidation (){
for textfield in textfieldCollection {
if textfield.text!.isEmpty || segmented.selectedSegmentIndex == -1 {
alertMethod()
} else {
self.dismiss(animated: true, completion: nil)
}
}
}
@IBAction func addButtonPressed(_ sender: UIButton) {
save()
textfieldValidation()
}
func save(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let newGame = GameMo(context: appDelegate.persistentContainer.viewContext)
newGame.goal = (Int32(goal.text ?? "0")!)
newGame.rivalGoal = (Int32(rivalGoal.text ?? "0")!)
newGame.shot = (Int32(shots.text ?? "0")!)
newGame.rivalShot = (Int32(rivalsShots.text ?? "0")!)
newGame.nouveau = true
newGame.date = DateManager.dateLong()
appDelegate.saveContext()
}
}
Class WelcomeViewController: UICollectionViewDelegate, UICollectionViewDataSource {
var ops: [BlockOperation] = []
lazy var context : NSManagedObjectContext = {
let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
return appDelegate.persistentContainer.viewContext
}()
lazy var fetchRequestController : NSFetchedResultsController<GameMo> = {
let fetchRequest = NSFetchRequest<GameMo>(entityName: "Game")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "date", ascending: false)]
let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil)
frc.delegate = self
do {
try frc.performFetch()
if let fetchedObjects = frc.fetchedObjects {
print("Fetch Request Activated")
self.gamesMo = fetchedObjects
}
} catch{
fatalError("Failed to fetch entities: \(error)")
}
return frc
}()
override func viewDidLoad() {
super.viewDidLoad()
fetchRequestController.delegate = self
try? fetchRequestController.performFetch()
}
deinit {
for o in ops { o.cancel() }
ops.removeAll()
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return gamesMo?.filter{$0.nouveau == true}.count ?? 0
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
if let gameIndex = gamesMo?.filter({$0.nouveau == true})[indexPath.row] {
let userGameScore = gameIndex.goal
let rivalGameScore = gameIndex.rivalGoal
if let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "FormCell", for: indexPath) as? FormCollectionViewCell {
cell.setCell(userScores: Int(userGameScore), rivalScores: Int(rivalGameScore) )
return cell
}
}
return UICollectionViewCell ()
}
}
extension WelcomeViewController: NSFetchedResultsControllerDelegate {
func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
}
func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
switch type {
case .insert:
print("insert")
print(gamesMo?.count)
ops.append(BlockOperation(block: { [weak self] in
self?.collectionView.insertItems(at: [newIndexPath!])
}))
case .delete:
ops.append(BlockOperation(block: { [weak self] in
self?.collectionView.deleteItems(at: [indexPath!])
}))
case .update:
ops.append(BlockOperation(block: { [weak self] in
self?.collectionView.reloadItems(at: [indexPath!])
}))
case .move:
ops.append(BlockOperation(block: { [weak self] in
self?.collectionView.moveItem(at: indexPath!, to: newIndexPath!)
}))
@unknown default:
break
}
}
func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
print("TableView endupdates")
collectionView.performBatchUpdates({ () -> Void in
for op: BlockOperation in self.ops { op.start() }
}, completion: {(finished) -> Void in self.ops.removeAll() })
}
}
您可以簡單地在WelcomeViewController
的viewDidAppear
中執行performFetch
來解決此問題。
class WelcomeViewController: UIViewController {
//...
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
fetchRequestController.delegate = self
try? fetchRequestController.performFetch()
}
}
修改save()
以使用saveContext
保存核心數據上下文。
func save(){
let appDelegate = UIApplication.shared.delegate as! AppDelegate
//...
appDelegate.saveContext()
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.