簡體   English   中英

Swift - 使用Long Gesture Recognizer拖放TableViewCell

[英]Swift - Drag And Drop TableViewCell with Long Gesture Recognizer

所以我看過很多關於重新排序與使用“編輯模式”相關的單元格的帖子,但沒有解決我遇到的問題。 (對不起,如果我錯了)。

我正在構建一個排名應用程序,並尋找一種方法來使用長手勢識別器來重新排序我的UITableView中的單元格。 基本上,用戶將能夠與他們的朋友重新排序並“排列”一組中充滿字符串的單元格。

我會使用導航欄中使用“編輯”欄按鈕項的標准路線,但我使用導航欄的右上角已經將新字符串添加到tableview。 (下圖描繪了我的意思)。

到目前為止,我已經添加了`

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

    lpgr.minimumPressDuration = 1.0;
    tableView.addGestureRecognizer(lpgr)`

到我的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!

}

我在互聯網上所提供的所有資源最終都顯示了一個巨大的,長期的功能添加劑列表,以獲得所需的結果,但這些例子涉及核心數據。 在我看來,必須有一個更容易的方法來簡單地重新排序tableview單元格長按?

在此輸入圖像描述

戴夫的回答很棒。 這是本教程的swift 4版本:

WayPointCell是您的CustomUITableViewCellwayPoints是UITableView的dataSource數組

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

override func viewDidLoad() {
    super.viewDidLoad()

    let longpress = UILongPressGestureRecognizer(target: self, action: #selector(longPressGestureRecognized(gestureRecognizer:)))
    self.tableView.addGestureRecognizer(longpress)
}

然后實現方法:

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
}

給這個教程一個鏡頭,你可能會在20分鍾內啟動並運行:

偉大的Swift拖放教程

這很容易。 我只開發了3個月,我能夠實現這一點。 我也嘗試了其他幾個,這是我能理解的。

它是用Swift編寫的,它實際上是剪切和粘貼的。 將longPress代碼添加到viewDidLoad,然后將該函數粘貼到類的“body”中。 本教程將指導您,但沒有更多內容。

代碼的快速說明 :此方法使用switch語句來檢測longPress是剛剛開始,更改還是默認情況。 每種情況都運行不同的代碼。 它會拍攝長按單元格的快照/圖片,隱藏單元格並移動快照。 完成后,它將取消隱藏您的單元格並從視圖中刪除快照。

警告 :我要提醒的是,雖然這種拖放看起來很棒並且接近完美,但似乎存在一個問題,即在拖動最低/最低單元格下方的單元格時它會崩潰。

拖放崩潰問題

從iOS 11開始,這可以通過實現內置的UITableView拖放委托來實現。

您將在這個類似問題的答案中找到有關如何實現它們的詳細說明: https//stackoverflow.com/a/57225766/10060753

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM