简体   繁体   English

TableView 滑动删除:如何以编程方式取消滑动

[英]TableView Swipe to Delete: How to Programmatically Un-swipe

I am using a the swipe to delete feature in the tableview to delete selected cells.我正在使用表格视图中的滑动删除功能来删除选定的单元格。 You swipe it to the left to reveal a delete button.您将其向左滑动以显示删除按钮。 My code works well and deletes like it should.我的代码运行良好,可以正常删除。

I am also including a UIAlertController to give the user of the app a single last chance from making a mistake.我还包含了一个 UIAlertController,为应用程序的用户提供最后一次避免出错的机会。 What I would like to do is if the user selects "Cancel" is have the cell "un-swipe" and return to its original position.我想要做的是,如果用户选择“取消”,则让单元格“取消滑动”并返回其原始位置。 Is there a way to do this?有没有办法做到这一点?

您可以关闭 tableView 上的编辑

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

I came across this question trying to do the same thing.我遇到了这个问题,试图做同样的事情。 I thought there had to be a better solution that reloading the table, so I did some further research and found the following.我认为必须有一个更好的解决方案来重新加载表,所以我做了一些进一步的研究并发现了以下内容。

tableView.setEditing(false, animated: true)

here's a little more code (Swift 3) to show it in use这里有更多代码(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]
}

I have had a similar question and found your question searching for an answer.我有一个类似的问题,发现你的问题正在寻找答案。 Based on the lack of answers here, I assumed I had to figure it out myself.基于这里缺乏答案,我认为我必须自己弄清楚。 Here is my issue and how I solved it.这是我的问题以及我如何解决它。 I hope it works for you, since I solved it extremely simple.我希望它对你有用,因为我解决了它非常简单。

I have an app with a start screen that shows a table with several tracks.我有一个带有开始屏幕的应用程序,该屏幕显示一个包含多个轨道的表格。 When you select a track you can either show the track details, show the track on a map (with MapView) or delete the track.当您选择一条轨迹时,您可以显示轨迹详细信息、在地图上显示轨迹(使用 MapView)或删除轨迹。

在此处输入图片说明

However, when you first use the app, the table is empty and shows a single table cell: "No saved tracks".但是,当您第一次使用该应用程序时,表格是空的,并显示一个表格单元格:“没有保存的曲目”。

在此处输入图片说明

This means the table is empty and you can't show track details, a track map or delete the track.这意味着该表为空,您无法显示曲目详细信息、曲目地图或删除曲目。 I wanted to make sure that if the table is empty, you get a different message and the left swipe is undone.我想确保如果桌子是空的,你会收到一条不同的消息,并且向左滑动被撤消。

在此处输入图片说明

The code is an overige of funk -tableView:editActionsForRowAtIndexPath indexPath:代码是 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]
}

The important part here is the "guard else" statement, where the code is executed when there is no track saved.这里重要的部分是“guard else”语句,当没有轨道保存时,代码会在这里执行。 Basically, the swipi shows a different message "No tracks" and when this action button is clicked, the table will be reloaded and the swipe is undone.基本上,swipi 会显示一条不同的消息“无轨道”,当单击此操作按钮时,将重新加载表格并取消滑动。 Since you use a UIAlertController, the same principle applies.由于您使用 UIAlertController,因此适用相同的原则。 The above methods works almost exactly the same as a UIAlertController and you can also reload your table after the user selects the "Cancel" button.上述方法的工作原理与 UIAlertController 几乎完全相同,您还可以在用户选择“取消”按钮后重新加载表格。

As I said, it is extremely simple and perhaps not meeting your expectations, but it does unswipe your left swipe after the user click "Cancel".正如我所说,它非常简单,可能不符合您的期望,但是在用户单击“取消”后它会取消您的左滑。 I hope it works for you.我希望这个对你有用。

I have followed this approach and it works quite well我遵循了这种方法并且效果很好

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)
        
    }

When the user cancel the operation I try to reload this table cell for discarding the swipe state.当用户取消操作时,我尝试重新加载此表格单元格以丢弃滑动状态。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM