表删除操作删除单元格内容但不删除单元格本身?

时间:2017-01-26 14:41:09

标签: ios swift uitableview fetch

我的表有一个删除功能,它是一个fetch控制器的委托。当我滑动删除一行时,它会清除对象并删除其数据,但该单元格仍然是一个空行。

我的fetch和table代码看起来像这样,任何想法为什么它也不会删除行?:

 func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
            switch (type) {
            case .update:
                if let indexPath = indexPath, let cell = workoutDesignerTable.cellForRow(at: indexPath) as? RoutineTableViewCell {
                    configure(cell, at: indexPath)
                }
                break;
            default:
                print("...")
            }
        }
    }

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {

        let delete = UITableViewRowAction(style: .destructive, title: "Delete") { (action, indexPath) in
            let UserExercise = self.fetchedResultsController.managedObjectContext
            UserExercise.delete(self.fetchedResultsController.object(at: indexPath))
            do {
                try UserExercise.save()
            } catch {
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
            self.workoutDesignerTable.reloadData()
        }

        let edit = UITableViewRowAction(style: .normal, title: "Edit") { (action, indexPath) in
            let cell = tableView.cellForRow(at: indexPath)
            self.updateExercise = self.fetchedResultsController.object(at: indexPath)
            self.performSegue(withIdentifier: self.segueEditUserExerciseViewController, sender: cell)
        }
            edit.backgroundColor = UIColor.lightGray
            return [delete, edit]
    }

以下问题的图片:

enter image description here

enter image description here

enter image description here

我添加了以下未解决问题的功能

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        let UserExercise = fetchedResultsController.managedObjectContext
        UserExercise.delete(fetchedResultsController.object(at: indexPath))
        do {
            try UserExercise.save()
        } catch {
            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
    tableView.deleteRows(at: [indexPath], with: .fade)
}

这里也是请求的numberOfRowsInSection

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    guard let userExercises = fetchedResultsController.fetchedObjects else { return 0 }
    return userExercises.count
}

enter image description here

我已经添加了上面的控制台打印,以便在删除对象的打印后显示,如果这有助于缩小范围,则显示为有错误

添加了下面的fetchresultscontroller代码

fileprivate lazy var fetchedResultsController: NSFetchedResultsController<UserExercise> = {

    let fetchRequest: NSFetchRequest<UserExercise> = UserExercise.fetchRequest()
    if self.userRoutine == nil {
        fetchRequest.predicate = NSPredicate(format: "usersroutine == nil")
    } else if self.userRoutine != nil {
        fetchRequest.predicate = NSPredicate(format: "usersroutine.name == %@", self.userRoutine!)
    }
        fetchRequest.sortDescriptors = [NSSortDescriptor(key: "dateCreated", ascending: true)]

    //controller config
    let fetchedResultsController = NSFetchedResultsController(fetchRequest: fetchRequest, managedObjectContext: self.persistentContainer.viewContext, sectionNameKeyPath: nil, cacheName: nil)

    fetchedResultsController.delegate = self
    return fetchedResultsController
}()

附加控制器代表代码:

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

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

    // MARK: - ADDING TABLE ROW AND EDITORIAL FEATURES

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {
        switch (type) {
        case .update:
            if let indexPath = indexPath, let cell = workoutDesignerTable.cellForRow(at: indexPath) as? RoutineTableViewCell {
                configure(cell, at: indexPath)
            }
            break;
        default:
            print("...")
        }
    }
}

2 个答案:

答案 0 :(得分:3)

你需要做3个步骤才能达到你想要的效果。 检测滑动,从模型中删除,更新视图。 这是一个例子:

override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) { // Detect Swipe
    if editingStyle == .delete {
        restaurantNames.remove(at: indexPath.row) // Remove from Model
    }
    tableView.deleteRows(at: [indexPath], with: .fade) // Update view
}

答案 1 :(得分:2)

首先,添加此功能(Mago提到)。

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
    if editingStyle == .delete {
        let UserExercise = fetchedResultsController.managedObjectContext
        UserExercise.delete(fetchedResultsController.object(at: indexPath))
        do {
            try UserExercise.save()
        } catch {
            let nserror = error as NSError
            fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
        }
    }
}

请注意,我们不会在此处重新加载tableview。 tableview会自动为您删除单元格,因此您只需要担心更新数据源。

有关使用NSFetchedResultsControllers here的精彩教程,了解有关如何使用它们的详细信息。另外,here's官方文档。

编辑以下是您需要在Swift中实现的NSFetchedResultsControllerDelegate方法的实现:

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:
        tableView.insertRows(at: [newIndexPath!], with: .automatic)
    case .delete:
        tableView.deleteRows(at: [indexPath!], with: .automatic)
    case .update:
        tableView.reloadRows(at: [indexPath!], with: .automatic)
    case .move:
        tableView.moveRow(at: indexPath!, to: newIndexPath!)
    }
}

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

您基本上将获取的结果控制器产生的更改映射到tableview。