使用Swift 3和CoreData删除表视图行

时间:2017-02-16 04:51:07

标签: swift core-data

我正在尝试实施滑动以删除我的应用中的表格视图单元格而且我遇到了崩溃:

  

'无效更新:第0节中的行数无效。更新后的现有部分中包含的行数(1)必须等于更新前该部分中包含的行数(1),再加上或减去从该部分插入或删除的行数(插入0,删除1),加上或减去移入或移出该部分的行数(0移入,0移出)。'

我有我的ViewController,在ViewControllerDataSource文件中,我符合UITableViewDataSource

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate,
        let managedObjectContext = appDelegate.managedObjectContext, editingStyle == .delete else { return }

    let request: NSFetchRequest<Meditation> = NSFetchRequest(entityName: "Meditation")
    let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
    request.sortDescriptors = [sortDescriptor]

    if let sessions = try? managedObjectContext.fetch(request) as [Meditation] {
        managedObjectContext.delete(sessions[indexPath.row])

        tableView.deleteRows(at: [indexPath], with: .fade)
        fetchEntries {
            tableView.reloadData()
        }
    }
}

这是fetchEntries的样子

func fetchEntries(completion: (() -> Void)? = nil) {
    guard let appDelegate = UIApplication.shared.delegate as? AppDelegate,
        let managedObjectContext = appDelegate.managedObjectContext
        else { return }

    var arrayOfEntries: [Entry] = []
    let request: NSFetchRequest<Meditation> = NSFetchRequest(entityName: "Meditation")
    let sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
    request.sortDescriptors = [sortDescriptor]

    if let objects = try? managedObjectContext.fetch(request) as [Meditation] {
        meditationSessions = objects

        for (index, object) in objects.enumerated() {
            // set some values that correspond to visual elements in the cell

            let timeLabel = lengthMinutesLabel(minutesString: lengthMinutes(object.length))

            let entry = Entry(
                sessionLength: lengthMinutes(object.length),
                sessionTimeUnit: timeLabel,
                sessionStartTime: "\(object.date.format())",
                sessionJournalEntry: object.journalEntry,
                sessionStreakTop: showStreak.top,
                sessionStreakBottom: showStreak.bottom
            )

            arrayOfEntries.append(entry)
            self.arrayOfEntries = arrayOfEntries
        }
    }

    completion?()
}

我不太确定我在这里做错了导致这次崩溃的原因。遗憾的是,如果崩溃是由竞争条件引起的,则CoreData删除功能没有完成块。

我为tableView:editingStyle:函数的最后7-9行尝试了各种不同的操作顺序无济于事。任何的意见都将会有帮助。谢谢!

3 个答案:

答案 0 :(得分:3)

  

更新了swift 3:

如果要在使用Core Data时删除UITableView行/单元格,请在下面的代码行中使用:

import CoreData

// MARK: - 变量声明

@IBOutlet weak var mTableView: UITableView!
var manageObjectContext: NSManagedObjectContext!
var eventArray = [Event]()  // Where **Event** is an model name

// MARK: - ViewController LifeCycle Methods

override func viewDidLoad() {
    super.viewDidLoad()
    manageObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
    self.loadSaveData()
}

//从tableview中删除特定单元格/行

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    let eventArrayItem = eventArray[indexPath.row]

    if editingStyle == .delete {
        manageObjectContext.delete(eventArrayItem)

        do {
            try manageObjectContext.save()
        } catch let error as NSError {
            print("Error While Deleting Note: \(error.userInfo)")
        }
    }
    self.loadSaveData()
}

// MARK: - 实例方法

func loadSaveData()  {

    let eventRequest: NSFetchRequest<Event> = Event.fetchRequest()
    do{
        eventArray = try manageObjectContext.fetch(eventRequest)
        self.mTableView.reloadData()
    }catch
    {
        print("Could not load save data: \(error.localizedDescription)")
    }
}

答案 1 :(得分:1)

当你删除coreData中的数据时,除非你保存动作,否则它不会被coreData保存。删除操作应该是这样的..

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
  if editingStyle == .delete {
    managedObjectContext.delete(sessions[indexPath.row])
    do {
      try managedObjectContext.save()
      tableView.reloadData()
    } catch let error as NSError {
      print("Could not save. \(error), \(error.userInfo)")
    }
  }
}

答案 2 :(得分:1)

我认为原因在于&#34;额外的&#34;致电tableView.reloadData()。只要您拨打tableView.deleteRows,就不应该拨打reloadData - 所以要么调用其中一个,要么可以依赖,如果你想要一个淡入淡出动画(deleteRows)或者不