【问题标题】:TableView Swipe to Delete: How to Programmatically Un-swipeTableView 滑动删除:如何以编程方式取消滑动
【发布时间】:2015-08-18 16:53:45
【问题描述】:

我正在使用表格视图中的滑动删除功能来删除选定的单元格。您将其向左滑动以显示删除按钮。我的代码运行良好,可以正常删除。

我还包括一个 UIAlertController,以便为应用程序的用户提供最后一次犯错的机会。我想要做的是,如果用户选择“取消”是让单元格“取消滑动”并返回其原始位置。有没有办法做到这一点?

【问题讨论】:

  • 在 deleteRowsAtIndexPath 之前复制所有单元格数据,如果他们点击取消,只需将其换回并重新加载 tableView。

标签: ios swift uitableview


【解决方案1】:

你可以关闭tableView上的编辑

[self.tableView setEditing:NO animated:YES];

【讨论】:

  • 从 iOS11 开始不再需要(实际上也不起作用)。要以编程方式关闭滑动视图,请使用 true 或 false 值调用“completionHandler”(设置滑动操作时 UIContextualAction.Handler 的第三个参数)。 stackoverflow.com/a/49995770/1204250
【解决方案2】:

我遇到了这个问题,试图做同样的事情。我认为必须有一个更好的解决方案来重新加载表格,所以我做了一些进一步的研究并发现了以下内容。

tableView.setEditing(false, animated: true)

这里还有一些代码 (Swift 3) 来展示它的使用情况

    // Custom cell edit actions
func tableView(_ tableView: UITableView, editActionsForRowAt: IndexPath) -> [UITableViewRowAction]? {
    let delete = UITableViewRowAction(style: .destructive, title: "Delete") {(rowAction: UITableViewRowAction, indexPath: IndexPath) -> Void in

        let refreshAlert = UIAlertController(title: "Delete", message: "Are you sure you want to delete this item.", preferredStyle: UIAlertControllerStyle.alert)

        refreshAlert.addAction(UIAlertAction(title: "Yes", style: .default, handler: { (action: UIAlertAction!) in
            let context = self.fetchedResultsController.managedObjectContext
            context.delete(self.fetchedResultsController.object(at: indexPath))

            do {
                try context.save()
            } catch {
                let nserror = error as NSError
                fatalError("Unresolved error \(nserror), \(nserror.userInfo)")
            }
        }))

        refreshAlert.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: { (action: UIAlertAction!) in
            // if the user presses cancel, slide the cell back
            tableView.setEditing(false, animated: true)
        }))

        self.present(refreshAlert, animated: true, completion: nil)

    }

    let editAction = UITableViewRowAction(style: .normal, title: "Edit") { action, index in
        print("edit button tapped")
    }

    editAction.backgroundColor = .orange


    return [editAction, delete]
}

【讨论】:

    【解决方案3】:

    我有一个类似的问题,并发现您的问题正在寻找答案。由于这里没有答案,我认为我必须自己弄清楚。这是我的问题以及我如何解决它。我希望它对你有用,因为我解决它非常简单。

    我有一个带有开始屏幕的应用程序,它显示了一个包含多个曲目的表格。当您选择一个轨迹时,您可以显示轨迹详细信息、在地图上显示轨迹(使用 MapView)或删除轨迹。

    但是,当您第一次使用该应用程序时,表格是空的,并显示一个表格单元格:“没有保存的曲目”。

    这意味着表格是空的,您无法显示赛道详情、赛道地图或删除赛道。我想确保如果桌子是空的,你会收到一条不同的消息,并且左滑动被撤消。

    代码是 funk -tableView:editActionsForRowAtIndexPath indexPath:

    override func tableView(tableView: UITableView, editActionsForRowAtIndexPath indexPath: NSIndexPath) -> [UITableViewRowAction]? {
    
        let selectedRow = indexPath.row
    
        guard self.savedTracks.count > 0 else {
        //There are no saved tracks, the action cannot be executed.
            let faultAction = UITableViewRowAction(style: .Normal, title: "No tracks", handler: { (action, indexPath) -> Void in
    
                self.trackOverviewTable.reloadData() //Simply reload the table view after the action button is hit.
            })
    
            return [faultAction]
        }
    
        //Show track details
        let detailsAction = UITableViewRowAction(style: .Default, title: "Details") { (action, indexPath) -> Void in
    
            print("I now selected the track details view.\n")
            self.newTrack = self.savedTracks[selectedRow]
            self.performSegueWithIdentifier("showTrackDetails", sender: self)
        }
    
        //Show track map
        let mapAction = UITableViewRowAction(style: .Normal, title: "Map") { (action, indexPath) -> Void in
    
            print("I now selexted the track map view.\n")
            self.newTrack = self.savedTracks[selectedRow]
            self.performSegueWithIdentifier("showTrackMap", sender: self)
        }
    
        //Delete the selected track
        let deleteAction = UITableViewRowAction(style: .Default, title: "Delete") { (action, indexPath) -> Void in
    
            print("I now pressed the delete button.\n")
            self.savedTracks.removeAtIndex(selectedRow)
            if self.savedTracks.count > 0 {
                self.trackOverviewTable.deleteRowsAtIndexPaths([indexPath], withRowAnimation: .Fade)
            } else {
                self.trackOverviewTable.reloadData()
            }
        }
    
        detailsAction.backgroundColor = UIColor(colorLiteralRed: 21.0/255.0, green: 175.0/255.0, blue: 253.0/255.0, alpha: 0.8)
        mapAction.backgroundColor = UIColor(colorLiteralRed: 37.0/255.0, green: 155.0/255.0, blue: 253.0/255.0, alpha: 0.8)
    
        return [deleteAction, mapAction, detailsAction]
    }
    

    这里的重要部分是“guard else”语句,当没有保存轨道时执行代码。基本上,swipi 显示不同的消息“无曲目”,当单击此操作按钮时,将重新加载表格并撤消滑动。由于您使用 UIAlertController,因此适用相同的原则。上述方法与 UIAlertController 几乎完全相同,您也可以在用户选择“取消”按钮后重新加载表。

    正如我所说,它非常简单,可能无法满足您的期望,但它确实会在用户单击“取消”后取消您的左滑动。我希望它对你有用。

    【讨论】:

      【解决方案4】:

      我采用了这种方法,效果很好

      private func onDeleteNote(noteIdx: Int) {
              let noteToDelete: Note = myNotes[noteIdx]
              
              let alertViewController = UIAlertController(title: "¿Would you like to delete this note?", message: "The Note \(noteToDelete.title) will be delete", preferredStyle: .alert)
              
              alertViewController.addAction(UIAlertAction(title: "Delete", style: .destructive) { (UIAlertAction) in
                  print("Delete note")
              })
              alertViewController.addAction(UIAlertAction(title: "Cancel", style: .cancel) { (UIAlertAction) in
                  print("Delete note was cancel")
                  self.myNotesTable.reloadRows(at: [IndexPath(row: noteIdx, section: 0)], with: .right)
              })
              
              present(alertViewController, animated: true, completion: nil)
              
          }
      

      当用户取消操作时,我尝试重新加载此表格单元格以放弃滑动状态。

      【讨论】:

        猜你喜欢
        • 2012-03-17
        • 2021-05-08
        • 1970-01-01
        • 2016-07-06
        • 2016-08-01
        • 1970-01-01
        • 1970-01-01
        • 2016-08-09
        • 1970-01-01
        相关资源
        最近更新 更多