0

シンプルカウンターアプリを作成しました。 CoreDataを使用してデータを格納します。モデルでは、属性「値」(Int64)と「位置」(Int16)を持つ「カウンタ」という名前のエンティティが1つあります。 2番目の属性はtableViewのpositionです。ユーザーはカウンタを追加、削除、または増やすことができます。私はまた、NSFetchedResultsControllerを使用して私のtableViewを設定します。アプリケーションは動作しますが、たとえば5つのカウンタを追加して値を変更し、2番目と3番目の値を削除して新しい値を追加すると、カウンタはtableViewの最後に挿入されません(ビデオはhttps://youtu.be/XXyuEaobd3cです)。私のコードに何が問題なのですか?NSFetchedResultsControllerが間違ったindexPathに項目を追加しました

import UIKit 
import CoreData 

class TableViewController: UITableViewController, NSFetchedResultsControllerDelegate { 

let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 

var frc: NSFetchedResultsController<Counter> = { 
    let fetchRequest: NSFetchRequest<Counter> = Counter.fetchRequest() 
    let sortDescriptor = NSSortDescriptor(key: "position", ascending: true) 
    fetchRequest.sortDescriptors = [sortDescriptor] 
    let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext 
    let frc = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: context, sectionNameKeyPath: nil, cacheName: nil) 
    do { 
     try frc.performFetch() 
    } catch { 
     print(error) 
    } 
    return frc 
}() 


@IBAction func addCounter(_ sender: UIBarButtonItem) { 
    let counter = Counter(context: context) 
    counter.value = 0 
    counter.position = Int16(frc.fetchedObjects!.count) 
    do { 
     try context.save() 
    } catch { 
     print(error) 
    } 

} 

@IBAction func longPressed(_ sender: UILongPressGestureRecognizer) { 
    if sender.state == UIGestureRecognizerState.began { 
     let touchPoint = sender.location(in: self.view) 
     if let indexPath = tableView.indexPathForRow(at: touchPoint) { 
      // your code here, get the row for the indexPath or do whatever you want 
      let counter = frc.object(at: indexPath) 
      counter.value = 0 

      do { 
       try context.save() 
      } catch { 
       print(error) 
      } 
     } 
    } 

} 


override func viewDidLoad() { 
    super.viewDidLoad() 

    frc.delegate = self 
} 


// MARK: - Table view data source 

override func numberOfSections(in tableView: UITableView) -> Int { 
    guard let sections = frc.sections?.count else {return 0} 
    return sections 
} 

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    guard let sections = frc.sections else {return 0} 
    return sections[section].numberOfObjects 
} 


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) 
    let counter = frc.object(at: indexPath) 
    cell.textLabel!.text! = String(counter.value) 

    return cell 
} 

func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    tableView.beginUpdates() 
} 

func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) { 
    switch type { 
    case .insert: 
     guard let indexPath = newIndexPath else {return} 
     tableView.insertRows(at: [indexPath], with: .fade) 
    case .delete: 
     guard let indexPath = indexPath else {return} 
     tableView.deleteRows(at: [indexPath], with: .fade) 
    case .update: 
     guard let indexPath = indexPath else {return} 
     let cell = tableView.cellForRow(at: indexPath) 
     let counter = frc.object(at: indexPath) 
     cell?.textLabel?.text = String(counter.value) 
    default: 
     break 
    } 
} 

func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) { 
    tableView.endUpdates() 
} 

override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 
    let counter = frc.object(at: indexPath) 
    counter.value += Int64(1) 

    do {try context.save()} 
    catch {print(error)} 

    tableView.deselectRow(at: indexPath, animated: true) 
} 

    // Override to support editing the table view. 
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { 
    if editingStyle == .delete { 
      let counter = frc.object(at: indexPath) 
      context.delete(counter) 

     do { 
      try context.save() 
     } catch { 
      print(error) 
     } 
    } 
} 

}

答えて

-1

あなたは間違った方法で位置を追加しています。 は、あなたがA1、A2、A3、A4、A5

はその後、A2、A3

は、その後、あなたがので、新しいの追加 A1、A4、A5

を持っている、削除

を持っていると仮定してみましょう1つはB3であり、カウントは3となるので、 A1、B3、A4、A5

他の行を追加するとB4になります。

この順序は、並べ替え順によるものです。

あなたは最後にフェッチされたオブジェクトを取得することで、この問題を解決し、位置をインクリメントされ、その後、発生することができます

A1、A4、A5、B6、B7

関連する問題