Swift - 使用Long Gesture Recognizer拖放TableViewCell

CL8*_*989 6 uitableview uigesturerecognizer ios swift

所以我看过很多关于重新排序与使用"编辑模式"相关的单元格的帖子,但没有解决我遇到的问题.(对不起,如果我错了).

我正在构建一个排名应用程序,并寻找一种方法来使用长手势识别器来重新排序我的UITableView中的单元格.基本上,用户将能够与他们的朋友重新排序并"排列"一组中充满字符串的单元格.

我会使用导航栏中使用"编辑"栏按钮项的标准路线,但我使用导航栏的右上角已经将新字符串添加到tableview.(下图描绘了我的意思).

到目前为止,我已经添加了`

    var lpgr = UILongPressGestureRecognizer(target: self, action: "longPressDetected:")

    lpgr.minimumPressDuration = 1.0;
    tableView.addGestureRecognizer(lpgr)`
Run Code Online (Sandbox Code Playgroud)

到我的viewDidLoad方法,并开始创建以下函数:

    func longPressDetected(sender: AnyObject) {

    var longPress:UILongPressGestureRecognizer = sender as UILongPressGestureRecognizer
    var state:UIGestureRecognizerState = longPress.state

    let location:CGPoint = longPress.locationInView(self.tableView) as CGPoint
    var indexPath = self.tableView.indexPathForRowAtPoint(location)?

    var snapshot:UIView!
    var sourceIndexPath:NSIndexPath!

}
Run Code Online (Sandbox Code Playgroud)

我在互联网上所提供的所有资源最终都显示了一个巨大的,长期的功能添加剂列表,以获得所需的结果,但这些例子涉及核心数据.在我看来,必须有一个更简单的方法来简单地重新排序tableview单元格长按?

在此输入图像描述

Tee*_*etz 21

戴夫的回答很棒.这是本教程的swift 4版本:

WayPointCell是你的CustomUITableViewCell,wayPoints是UITableView的dataSource数组

首先,把它放在你的viewDidLoad中,就像Alfi提到的那样:

override func viewDidLoad() {
    super.viewDidLoad()

    let longpress = UILongPressGestureRecognizer(target: self, action: #selector(longPressGestureRecognized(gestureRecognizer:)))
    self.tableView.addGestureRecognizer(longpress)
}
Run Code Online (Sandbox Code Playgroud)

然后实现方法:

func longPressGestureRecognized(gestureRecognizer: UIGestureRecognizer) {

    let longpress = gestureRecognizer as! UILongPressGestureRecognizer
    let state = longpress.state
    let locationInView = longpress.location(in: self.tableView)
    var indexPath = self.tableView.indexPathForRow(at: locationInView)

    switch state {
    case .began:
        if indexPath != nil {
            Path.initialIndexPath = indexPath
            let cell = self.tableView.cellForRow(at: indexPath!) as! WayPointCell
            My.cellSnapShot = snapshopOfCell(inputView: cell)
            var center = cell.center
            My.cellSnapShot?.center = center
            My.cellSnapShot?.alpha = 0.0
            self.tableView.addSubview(My.cellSnapShot!)

            UIView.animate(withDuration: 0.25, animations: {
                center.y = locationInView.y
                My.cellSnapShot?.center = center
                My.cellSnapShot?.transform = CGAffineTransform(scaleX: 1.05, y: 1.05)
                My.cellSnapShot?.alpha = 0.98
                cell.alpha = 0.0
            }, completion: { (finished) -> Void in
                if finished {
                    cell.isHidden = true
                }
            })
        }

    case .changed:
        var center = My.cellSnapShot?.center
        center?.y = locationInView.y
        My.cellSnapShot?.center = center!
        if ((indexPath != nil) && (indexPath != Path.initialIndexPath)) {

            self.wayPoints.swapAt((indexPath?.row)!, (Path.initialIndexPath?.row)!)
            //swap(&self.wayPoints[(indexPath?.row)!], &self.wayPoints[(Path.initialIndexPath?.row)!])
            self.tableView.moveRow(at: Path.initialIndexPath!, to: indexPath!)
            Path.initialIndexPath = indexPath
        }

    default:
        let cell = self.tableView.cellForRow(at: Path.initialIndexPath!) as! WayPointCell
        cell.isHidden = false
        cell.alpha = 0.0
        UIView.animate(withDuration: 0.25, animations: {
            My.cellSnapShot?.center = cell.center
            My.cellSnapShot?.transform = .identity
            My.cellSnapShot?.alpha = 0.0
            cell.alpha = 1.0
        }, completion: { (finished) -> Void in
            if finished {
                Path.initialIndexPath = nil
                My.cellSnapShot?.removeFromSuperview()
                My.cellSnapShot = nil
            }
        })
    }
}

func snapshopOfCell(inputView: UIView) -> UIView {

    UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, false, 0.0)
    inputView.layer.render(in: UIGraphicsGetCurrentContext()!)
    let image = UIGraphicsGetImageFromCurrentImageContext()!
    UIGraphicsEndImageContext()
    let cellSnapshot : UIView = UIImageView(image: image)
    cellSnapshot.layer.masksToBounds = false
    cellSnapshot.layer.cornerRadius = 0.0
    cellSnapshot.layer.shadowOffset = CGSize(width: -5.0, height: 0.0)
    cellSnapshot.layer.shadowRadius = 5.0
    cellSnapshot.layer.shadowOpacity = 0.4
    return cellSnapshot
}

struct My {
    static var cellSnapShot: UIView? = nil
}

struct Path {
    static var initialIndexPath: IndexPath? = nil
}
Run Code Online (Sandbox Code Playgroud)

  • 当longPressGestureRecognizer到达屏幕底部时,如何滚动tableView呢? (2认同)

Dav*_*e G 8

给这个教程一个镜头,你可能会在20分钟内启动并运行:

伟大的Swift拖放教程

这很简单.我只开发了3个月,我能够实现这一点.我也尝试了其他几个,这是我能理解的.

它是用Swift编写的,它实际上是剪切和粘贴的.将longPress代码添加到viewDidLoad,然后将该函数粘贴到类的"body"中.本教程将指导您,但没有更多内容.

代码的快速说明:此方法使用switch语句来检测longPress是刚刚开始,更改还是默认情况.每种情况都运行不同的代码.它会拍摄长按单元格的快照/图片,隐藏单元格并移动快照.完成后,它将取消隐藏您的单元格并从视图中删除快照.

警告:我要提醒的是,尽管这种拖放看起来很棒并且接近完美,但似乎存在一个问题,即在拖动最低/最低单元格下方的单元格时它会崩溃.

拖放崩溃问题

  • 这是我见过的第一个教程,基本上只是"有效".感谢分享! (3认同)