tableViewCell拖拽移动并且交换

开发过程中,可能会遇上要求拖拽cell,移动到指定的位置,然后交换cell的位置。tableView协议可以满足,但是存在几个缺陷:
1.必须是编辑状态时才可拖拽。
2.可编辑状态是右边会有几条杠,对cell的显示会有压缩。
3.长按移动只有按住右边几条杠才能移动。

使用自定义方法,就是添加一个长按手势,然后对选择的cell进行copy,然后隐藏原先的cell(看起来cell就被我们拖拽出来了)。将copy出来的cell跟随着我们的手指的位置,在位置变化的过程中,根据Location去获取新的indexPath,然后交换两者,看起来就实现了拖拽交换。

demo地址

核心代码:

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.white
        tableView.frame = CGRect(x: 0, y: 100, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height)
        tableView.delegate = self
        tableView.dataSource = self
        view.addSubview(tableView)
        
        //手势
        let longPressGes = UILongPressGestureRecognizer(target: self, action: #selector(drapCell))
        longPressGes.minimumPressDuration = 0.5
        tableView.addGestureRecognizer(longPressGes)
    }

    ///处理手势
    @objc func drapCell(longPressGes: UILongPressGestureRecognizer) {
        switch longPressGes.state {
        case .began:
            let point = longPressGes.location(in: tableView)
            if let indexPath = tableView.indexPathForRow(at: point) {
                if indexPath.row != 0 {
                    originIndex = indexPath.row
                    if let cell = tableView.cellForRow(at: indexPath) {
                        moveCellImg = cell.snapshotView(afterScreenUpdates: false)
                        view.addSubview(moveCellImg!)
                        setMoveImgVPoint(longPressGes: longPressGes)
                        //将要拖动的原cell隐藏
                        cell.isHidden = true
                    }
                }
            }
        case .changed:
            let point = longPressGes.location(in: tableView)
            if let indexPath = tableView.indexPathForRow(at: point) {
                if indexPath.row != originIndex {
                    let sourceIndex = IndexPath(row: originIndex, section: 0)
                    tableView.moveRow(at: sourceIndex, to: indexPath)
                    array.exchangeObject(at: originIndex, withObjectAt: indexPath.row)
                    originIndex = indexPath.row
                }
            }
            setMoveImgVPoint(longPressGes: longPressGes)
        case.ended:
            let point = longPressGes.location(in: tableView)
            if let indexPath = tableView.indexPathForRow(at: point) {
                if indexPath.row == originIndex || originIndex == -1 {
                    resetMoveTableViewCellAnimation()
                    return
                }
                array.exchangeObject(at: originIndex, withObjectAt: indexPath.row)
            }
            resetMoveTableViewCellAnimation()
        default:
            resetMoveTableViewCellAnimation()
            break
        }
    }
    
    //cell跟随手指位置
    func setMoveImgVPoint(longPressGes: UILongPressGestureRecognizer) {
        let newPoin = longPressGes.location(in: view)
        moveCellImg?.x = newPoin.x - moveCellImg!.width / 2
        moveCellImg?.y = newPoin.y - moveCellImg!.height / 2
    }
    
    //结束动画
    func resetMoveTableViewCellAnimation() {
        moveCellImg?.removeFromSuperview()
        moveCellImg = nil
        tableView.reloadData()
    }

你可能感兴趣的:(tableViewCell拖拽移动并且交换)