开发过程中,可能会遇上要求拖拽cell,移动到指定的位置,然后交换cell的位置。tableView协议可以满足,但是存在几个缺陷:
1.必须是编辑状态时才可拖拽。
2.可编辑状态是右边会有几条杠,对cell的显示会有压缩。
3.长按移动只有按住右边几条杠才能移动。
使用自定义方法,就是添加一个长按手势,然后对选择的cell进行copy,然后隐藏原先的cell(看起来cell就被我们拖拽出来了)。将copy出来的cell跟随着我们的手指的位置,在位置变化的过程中,根据Location去获取新的indexPath,然后交换两者,看起来就实现了拖拽交换。
核心代码:
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()
}
网友评论