实现collectionViewCell的移动(长按或者直接拖拽)
2016-05-03 16:37
543 查看
最近在实现类似网易新闻的首页滑块的编辑效果: 长按后进入编辑界面, 然后可以通过拖拽实现cell的移动, 研究后发现两种实现方式: 第一种是直接利用系统提供的UICollectionView API实现移动, 不过只能在iOS9上面使用. 所以这里就介绍另外一种方式.
源码效果示例:
在这个手势的selector中通过获取到当前手势在collectionVIew的location来获取到一个indexPath, 如果这个indexPath是有效的, 那么就可以通过这个indexPath获取到对应的cell.
将获取到的cell截图, 然后将这个cell隐藏, 通过设置这个截图的frame使得这个截图跟随手指同步移动, 如果截图移动到了另外一个cell的位置, 则通过调用collectionView的方法将这两个cell交换位置, 同时需要更新collectionView的dataSource.
2 在selector中处理手势的响应
2.1 获取当前手势的位置
2.2 获取这个位置对应的在collectionView中的indexPath, 注意这个indexPath可能为nil(比如手指没有在cell的位置上时)
2.3 通过当前手势的状态不同的处理
2.3.1 case .Began 手势开始的时候
a. 记录下当前的indexPath以便于在手指移动的过程中进入.Changed状态的时候使用
b. 通过这个indexPath获取到对应的cell
c. 获取到这个cell截图
d. 并且设置截图的初始位置
e. 隐藏当前的cell
f. 将截图添加到collectionView中
2.3.2 case .Changed 手指在移动的时候
a. 如果在began状态中没有获取到截图直接返回
b. 设置截图的位置, 以达到和手指同步移动
c. 如果新获取到的indexPath有效并且和原来的不相同
d. 移动cell, 更新dataSource
e. 设置新的cell的属性
f. 更新当前的indexPath
2.3.3 case .End 手指离开屏幕的时候
a. 获取到当前移动完成的cell
b. 使用动画移除截图并且设置当前的移动完成的cell的属性
详细请移步源码, 如果您觉得有帮助,不妨给个star鼓励一下, 欢迎关注
源码效果示例:
原理部分
添加一个长按手势到UICollectionView上在这个手势的selector中通过获取到当前手势在collectionVIew的location来获取到一个indexPath, 如果这个indexPath是有效的, 那么就可以通过这个indexPath获取到对应的cell.
将获取到的cell截图, 然后将这个cell隐藏, 通过设置这个截图的frame使得这个截图跟随手指同步移动, 如果截图移动到了另外一个cell的位置, 则通过调用collectionView的方法将这两个cell交换位置, 同时需要更新collectionView的dataSource.
实现部分
在collectionView上添加一个长按手势let longGes = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressd(_:))) collectionView.addGestureRecognizer(longGes)
2 在selector中处理手势的响应
2.1 获取当前手势的位置
let location = ges.locationInView(self.collectionView)
2.2 获取这个位置对应的在collectionView中的indexPath, 注意这个indexPath可能为nil(比如手指没有在cell的位置上时)
// 当手指的位置不在collectionView的cell范围内时为nil let notSureIndexPath = self.collectionView.indexPathForItemAtPoint(location)
2.3 通过当前手势的状态不同的处理
2.3.1 case .Began 手势开始的时候
if let indexPath = notSureIndexPath { // 获取到的indexPath是有效的, 可以放心使用 // a. currentIndexPath = indexPath // b. let cell = collectionView.cellForItemAtIndexPath(indexPath)! // c. snapedImageView = getTheCellSnap(cell) deltaSize = CGSize(width: location.x - cell.frame.origin.x, height: location.y - cell.frame.origin.y) // d. snapedImageView.center = cell.center snapedImageView.transform = CGAffineTransformMakeScale(1.1, 1.1) // e. cell.alpha = 0.0 // f. collectionView.addSubview(snapedImageView) }
a. 记录下当前的indexPath以便于在手指移动的过程中进入.Changed状态的时候使用
b. 通过这个indexPath获取到对应的cell
c. 获取到这个cell截图
d. 并且设置截图的初始位置
e. 隐藏当前的cell
f. 将截图添加到collectionView中
2.3.2 case .Changed 手指在移动的时候
// a. if snapedImageView == nil { return } // b. snapedImageView.frame.origin.x = location.x - deltaSize.width snapedImageView.frame.origin.y = location.y - deltaSize.height // c. if let newIndexPath = notSureIndexPath, let oldIndexPath = currentIndexPath { if newIndexPath != oldIndexPath && newIndexPath.section == oldIndexPath.section {// 只在同一组中移动 // d. collectionView.moveItemAtIndexPath(oldIndexPath, toIndexPath: newIndexPath) // 更新dataSource // e. let cell = collectionView.cellForItemAtIndexPath(newIndexPath) cell?.alpha = 0.0 // f. currentIndexPath = newIndexPath } }
a. 如果在began状态中没有获取到截图直接返回
b. 设置截图的位置, 以达到和手指同步移动
c. 如果新获取到的indexPath有效并且和原来的不相同
d. 移动cell, 更新dataSource
e. 设置新的cell的属性
f. 更新当前的indexPath
2.3.3 case .End 手指离开屏幕的时候
if let oldIndexPath = currentIndexPath { // a. let cell = collectionView.cellForItemAtIndexPath(oldIndexPath)! // b. UIView.animateWithDuration(0.25, animations: {[unowned self] in self.snapedImageView.transform = CGAffineTransformIdentity self.snapedImageView.frame = cell.frame }, completion: {[unowned self] (_) in self. 4000 snapedImageView.removeFromSuperview() self.snapedImageView = nil self.currentIndexPath = nil cell.alpha = 1.0 }) }
a. 获取到当前移动完成的cell
b. 使用动画移除截图并且设置当前的移动完成的cell的属性
到目前位置, 设置好collectionView的datasource和delegate方法后就可以实现以下的效果了
详细请移步源码, 如果您觉得有帮助,不妨给个star鼓励一下, 欢迎关注
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 网易云音乐8亿用户背后的伤疤
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- 用于提取网易文件的hta代码
- 讲解iOS开发中基本的定位功能实现
- iOS中定位当前位置坐标及转换为火星坐标的方法
- js判断客户端是iOS还是Android等移动终端的方法
- iOS应用中UISearchDisplayController搜索效果的用法
- IOS开发环境windows化攻略
- iOS应用中UITableView左滑自定义选项及批量删除的实现
- 浅析iOS应用开发中线程间的通信与线程安全问题
- Swift中实现点击、双击、捏、旋转、拖动、划动、长按手势的类和方法介绍
- 检测iOS设备是否越狱的方法
- 基于Android中手势交互的实现方法
- .net平台推送ios消息的实现方法