先看效果:
拖拽cell排序
一、 UITableView有自带的cell拖拽排序功能,但是有个缺点,拖拽平移的手势只能在cell的最右侧,拖拽按钮上的图标也不方便更换,在此不在细说;
二、使用UICollectionView实现cell拖拽排序
视频中的效果是使用UICollectionView实现的;
UICollectionView部分的代码不再写了,就是常规的实现;以下只把拖拽手势实现的逻辑贴出来,仅供参考:
1、在listView: UICollectionView!上添加PanGesture手势:
self.listView.register(UINib(nibName: "RecordListCVCell", bundle: nil), forCellWithReuseIdentifier: "RecordListCVCell")
self.listView.contentInset = UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0)
let layout = UICollectionViewFlowLayout()
layout.scrollDirection = .vertical
layout.itemSize = CGSize(width: ScreenWidth - 32, height: 55)
self.listView.collectionViewLayout = layout
self.listView.reloadData()
panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:)))
panGesture!.isEnabled = true
panGesture!.delegate = self
self.listView.addGestureRecognizer(panGesture!)片
2、在UIGestureRecognizerDelegate代理方法中限制手势的作用范围:
这一步主要是防止 panGesture 与 listView滚动冲突
//限制拖拽手势的作用范围:仅左侧60pt宽度区域有效
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
guard gestureRecognizer == panGesture,
let pan = gestureRecognizer as? UIPanGestureRecognizer else {
return true
}
// 1. 获取触摸点坐标
let touchPoint = pan.location(in: listView)
// 2. 区域限制:仅左侧60pt宽度区域有效
guard touchPoint.x < 60 else {
return false // 超出区域不响应
}
return true
}
3、cell的平移操作:
//平移
@objc func handlePanGesture(_ panPress: UIPanGestureRecognizer) {
switch panPress.state {
case .began:
// 手势作用的位置
if let selectIndexPath = listView.indexPathForItem(at: panPress.location(in: listView)) {
// 找到当前的 cell
if let _ = listView.cellForItem(at: selectIndexPath) as? RecordListCVCell {
// 开始移动
listView.beginInteractiveMovementForItem(at: selectIndexPath)
}
}
break
case .changed:
// 更新移动的位置:只移动Y,移动时cell的中心点X会跑到0点位置,所以要 x = (ScreenWidth - 32) / 2.0 纠正过来
listView.updateInteractiveMovementTargetPosition(CGPoint(x: (ScreenWidth - 32) / 2.0, y: panPress.location(in: panPress.view).y))
break
case .ended:
// 结束移动
listView.endInteractiveMovement()
break
default:
listView.cancelInteractiveMovement()
break
}
}
4、在UICollectionViewDataSource代理中实现数据源的重新排序:
func collectionView(_ collectionView: UICollectionView, moveItemAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath){
//拖拽排序:更新数据源顺序
let element = dataList.remove(at: sourceIndexPath.row)
dataList.insert(element, at: destinationIndexPath.row)
self.listView.reloadData()
}