Using long press gesture to reorder cells in tableview?

前端 未结 6 552
灰色年华
灰色年华 2021-02-04 03:35

I want to be able to reorder tableview cells using a longPress gesture (not with the standard reorder controls). After the longPress is recognized I want the tableView to essent

6条回答
  •  时光说笑
    2021-02-04 04:09

    Swift 3 and no third party solutions

    First, add these two variables to your class:

    var dragInitialIndexPath: IndexPath?
    var dragCellSnapshot: UIView?
    

    Then add UILongPressGestureRecognizer to your tableView:

    let longPress = UILongPressGestureRecognizer(target: self, action: #selector(onLongPressGesture(sender:)))
    longPress.minimumPressDuration = 0.2 // optional
    tableView.addGestureRecognizer(longPress)
    

    Handle UILongPressGestureRecognizer:

    // MARK: cell reorder / long press
    
    func onLongPressGesture(sender: UILongPressGestureRecognizer) {
      let locationInView = sender.location(in: tableView)
      let indexPath = tableView.indexPathForRow(at: locationInView)
    
      if sender.state == .began {
        if indexPath != nil {
          dragInitialIndexPath = indexPath
          let cell = tableView.cellForRow(at: indexPath!)
          dragCellSnapshot = snapshotOfCell(inputView: cell!)
          var center = cell?.center
          dragCellSnapshot?.center = center!
          dragCellSnapshot?.alpha = 0.0
          tableView.addSubview(dragCellSnapshot!)
    
          UIView.animate(withDuration: 0.25, animations: { () -> Void in
            center?.y = locationInView.y
            self.dragCellSnapshot?.center = center!
            self.dragCellSnapshot?.transform = (self.dragCellSnapshot?.transform.scaledBy(x: 1.05, y: 1.05))!
            self.dragCellSnapshot?.alpha = 0.99
            cell?.alpha = 0.0
          }, completion: { (finished) -> Void in
            if finished {
              cell?.isHidden = true
            }
          })
        }
      } else if sender.state == .changed && dragInitialIndexPath != nil {
        var center = dragCellSnapshot?.center
        center?.y = locationInView.y
        dragCellSnapshot?.center = center!
    
        // to lock dragging to same section add: "&& indexPath?.section == dragInitialIndexPath?.section" to the if below
        if indexPath != nil && indexPath != dragInitialIndexPath {
          // update your data model
          let dataToMove = data[dragInitialIndexPath!.row]
          data.remove(at: dragInitialIndexPath!.row)
          data.insert(dataToMove, at: indexPath!.row)
    
          tableView.moveRow(at: dragInitialIndexPath!, to: indexPath!)
          dragInitialIndexPath = indexPath
        }
      } else if sender.state == .ended && dragInitialIndexPath != nil {
        let cell = tableView.cellForRow(at: dragInitialIndexPath!)
        cell?.isHidden = false
        cell?.alpha = 0.0
        UIView.animate(withDuration: 0.25, animations: { () -> Void in
          self.dragCellSnapshot?.center = (cell?.center)!
          self.dragCellSnapshot?.transform = CGAffineTransform.identity
          self.dragCellSnapshot?.alpha = 0.0
          cell?.alpha = 1.0
        }, completion: { (finished) -> Void in
          if finished {
            self.dragInitialIndexPath = nil
            self.dragCellSnapshot?.removeFromSuperview()
            self.dragCellSnapshot = nil
          }
        })
      }
    }
    
    func snapshotOfCell(inputView: UIView) -> UIView {
      UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, false, 0.0)
      inputView.layer.render(in: UIGraphicsGetCurrentContext()!)
      let image = UIGraphicsGetImageFromCurrentImageContext()
      UIGraphicsEndImageContext()
    
      let cellSnapshot = 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
    }
    

提交回复
热议问题