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

Posted

技术标签:

【中文标题】表删除操作删除单元格内容但不删除单元格本身?【英文标题】:Table Delete Action Deletes Cell Content but not Cell Itself? 【发布时间】:2017-01-26 14:41:08 【问题描述】:

我的表有一个删除函数,它是获取控制器的委托。当我滑动删除一行时,它会清除对象并删除其数据,但单元格仍保留为空行。

我的 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]
    

问题图片如下:

我添加了以下未解决问题的函数

    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

我已经添加了上面的控制台打印,以在删除对象的打印后显示,如果这有助于缩小范围,则该对象的打印似乎读作有问题

在下面添加了 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("...")
        
    

【问题讨论】:

您的numberOfItemsForRowAtIndexPath 方法是什么样的?这就是告诉您的 tableview 显示多少行的方法。 我没有那个特定的方法 jsut numberOfRowsInSection 和 CellForTowAt 哈哈抱歉我指的是这个方法(numberOfRowsInSection)。 现在为您将其添加到 OP 1 秒 我刚刚在该函数中运行了一个打印命令,即使在删除它显示运动计数为 1 因此行之后,所以再次必须使用删除函数来清除行或计数最有可能没有更新 【参考方案1】:

您需要执行 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

【讨论】:

resturantNames 在我的代码中会翻译成什么?我很确定这不会从表格中清除核心数据中的任何内容? 我认为您正在使用 Core Data。在我的例子中,我将它从我的餐厅名称数组中删除。在您的情况下,那行代码将从核心数据中删除您的数据。 我已经用我添加的新代码更新了图像下的 OP,它还没有解决问题,同样的问题 我认为您的问题在于您在表格上显示的行数,您能否分享告诉表格视图它有多少行的代码? 是的,我根据其他响应者的要求将其添加到 OP【参考方案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。表格视图会自动为您删除单元格,因此您只需要担心更新数据源即可。

有一个关于使用NSFetchedResultsControllershere 的精彩教程,以获取有关如何使用它们的更多信息。另外,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。

【讨论】:

如果这不起作用,您可能必须将 NSFetchedResultsController 委托属性设置为您的 VC,并处理适当的回调(这在我发布的第一个链接中有介绍)。 嗨,马克添加此功能并不能解决问题,不幸的是它完全相同。我也相信我已经将表格设置为委托和数据源 你指的是uitabelviewdelegate和uitableviewdatasource吗?我说的是 NSFetchedResultsControllerDelegate。 是的,我是,所以我只是将 NSFetchedResultsControllerDelegate = self 添加到 viewdidload 中? 需要在实例上设置属性,所以fetchedResultsController.delegate = self。看看这个链接,它会引导你完成每一步:raywenderlich.com/999/…

以上是关于表删除操作删除单元格内容但不删除单元格本身?的主要内容,如果未能解决你的问题,请参考以下文章

如何去掉EXCEL单元格内最后一个空格符

excelvba锁定单元格图片不被删除

Obj-C - 点击自定义表格视图单元格中的删除表格视图行按钮

在代码页中如何获取FastReport中一个单元格的值

表视图,如何将删除按钮放在前面?

删除空白单元格