长按移动cell
2015-09-29 18:24
281 查看
前言: 之前见过瀑布流中的cell,由手势拖动变换位置的效果,一直觉得很炫很神奇。今天无意在破船之家看到了这种效果的实现方法。最核心的位置变换只需掉俩个方法,然后由系统完成。所以很简单,没有想象中的那么复杂。
我们先从简单的Tableview开始。
效果如下
实现过程
给tableview添加长按手势。
在手势开始时,获取选中的cell,对cell截图。cell隐藏,截图的frame和cell的frame相同,也就是用截图替换掉cell。
为了良好的用户体验,将截图放大一点,并设置上阴影效果,让截图跃然于纸上。
手势移动时,移动截图。
移动数据源中数据位置,
移动cell的位置。调用这个方法。
手势结束时,移除截图,让cell重新显示出来。当然在这个过程中可以来点动画,让效果更炫点。
代码
添加长按手势的代码就不列出来了,这里是处理手势事件的方法。
if (!currentIndexPath) return; 因为如果选到了section的段头上,currentIndexPath是空值。所以要判断。
sourceIndexPath 表示的是交换后源cell的索引。也就是cell移动到了哪个位置上。
移动的核心代码就这俩句,[self.datas exchangeObjectAtIndex:currentIndexPath.row withObjectAtIndex:sourceIndexPath.row];和[self.tableView moveRowAtIndexPath:sourceIndexPath toInd
4000
exPath:currentIndexPath];先更新数据源,然后更新UI,这个没什么好讲的了。最后别忘记sourceIndexPath = currentIndexPath;移动后源cell的位置也发生变化,所以要更新哦。
CollectionView和上面的过程几乎一模一样。
附上效果图
TableView的Demo
CollectionView的Demo
我们先从简单的Tableview开始。
效果如下
实现过程
给tableview添加长按手势。
在手势开始时,获取选中的cell,对cell截图。cell隐藏,截图的frame和cell的frame相同,也就是用截图替换掉cell。
为了良好的用户体验,将截图放大一点,并设置上阴影效果,让截图跃然于纸上。
手势移动时,移动截图。
移动数据源中数据位置,
移动cell的位置。调用这个方法。
- (void)moveRowAtIndexPath:(NSIndexPath *)indexPath toIndexPath:(NSIndexPath *)newIndexPath
手势结束时,移除截图,让cell重新显示出来。当然在这个过程中可以来点动画,让效果更炫点。
代码
添加长按手势的代码就不列出来了,这里是处理手势事件的方法。
- (void)handleLongPress:(UILongPressGestureRecognizer *)longPress { CGPoint pressLocation = [longPress locationInView:self.tableView]; NSIndexPath *currentIndexPath = [self.tableView indexPathForRowAtPoint:pressLocation]; static NSIndexPath *sourceIndexPath = nil; static UIView *snapShot = nil; if (!currentIndexPath) return; if (longPress.state == UIGestureRecognizerStateBegan) { if (currentIndexPath) { // 0. 记录选中的indexPath sourceIndexPath = currentIndexPath; // 1. 截取cell上的图片 UITableViewCell *sourceCell = [self.tableView cellForRowAtIndexPath:sourceIndexPath]; snapShot = [self snapShotInView:sourceCell]; snapShot.frame = sourceCell.frame; snapShot.alpha = 0; [self.tableView addSubview:snapShot]; // 2. 对截图做动画,并隐藏cell [UIView animateWithDuration:0.5 animations:^{ snapShot.transform = CGAffineTransformMakeScale(1.05, 1.05); snapShot.alpha = 0.9; sourceCell.alpha = 0.0f; CGPoint o = snapShot.center; o.y = pressLocation.y; snapShot.center = o; } completion:^(BOOL finished) { sourceCell.hidden = YES; }]; } } else if (longPress.state == UIGestureRecognizerStateChanged) { // 移动截图 CGPoint o = snapShot.center; o.y = pressLocation.y; snapShot.center = o; if (![currentIndexPath isEqual:sourceIndexPath]) { // 数据交换 [self.datas exchangeObjectAtIndex:currentIndexPath.row withObjectAtIndex:sourceIndexPath.row]; // cell移动 [self.tableView moveRowAtIndexPath:sourceIndexPath toIndexPath:currentIndexPath]; // 更新indexPath sourceIndexPath = currentIndexPath; } } else if (longPress.state == UIGestureRecognizerStateEnded) { // 截图动画消失,并且显示cell UITableViewCell *sourceCell = [self.tableView cellForRowAtIndexPath:sourceIndexPath]; sourceCell.hidden = NO; sourceCell.alpha = 0.0f; [UIView animateWithDuration:0.25 animations:^{ snapShot.center = sourceCell.center; snapShot.transform = CGAffineTransformIdentity; sourceCell.alpha = 1.0f; } completion:^(BOOL finished) { [snapShot removeFromSuperview]; }]; } } - (UIView *)snapShotInView:(UIView *)inputView { UIView *snapShot = [inputView snapshotViewAfterScreenUpdates:NO]; snapShot.bounds = inputView.bounds; snapShot.layer.shadowOffset = CGSizeMake(-5, 0); snapShot.layer.shadowOpacity = 1; snapShot.layer.shadowRadius = 5.0; return snapShot; }
if (!currentIndexPath) return; 因为如果选到了section的段头上,currentIndexPath是空值。所以要判断。
sourceIndexPath 表示的是交换后源cell的索引。也就是cell移动到了哪个位置上。
移动的核心代码就这俩句,[self.datas exchangeObjectAtIndex:currentIndexPath.row withObjectAtIndex:sourceIndexPath.row];和[self.tableView moveRowAtIndexPath:sourceIndexPath toInd
4000
exPath:currentIndexPath];先更新数据源,然后更新UI,这个没什么好讲的了。最后别忘记sourceIndexPath = currentIndexPath;移动后源cell的位置也发生变化,所以要更新哦。
CollectionView和上面的过程几乎一模一样。
附上效果图
TableView的Demo
CollectionView的Demo
相关文章推荐
- 19.Android 清除按钮EditText - AIEditText
- 项目总结之关于JQuery一些常用的函数
- Eclipse自动生成所需的各种注释信息
- shell基础特性3
- 大写小,小写大
- RedHat 自定义用户环境
- vfork 挂掉的一个问题
- 设计模式详解
- iOS 9 适配
- 对json进行封装
- 动手学习TCP: 环境搭建
- C语言算法-猴子分桃问题
- 《统计学习方法》+朴素贝叶斯算法+C++代码(简单)实现
- Hibernate-二级缓存与查询缓存
- Mac OSX VirtualBox 裡的 Ubuntu 14.04 调整屏幕大小分辨率(转)
- 输入固定组的字符串
- HDFS序列化
- HTML5表单新增元素与属性 (续)
- LintCode -- 不同的路径 II
- C++进阶学习——单例模式的实现