您的位置:首页 > 其它

长按移动cell

2015-09-29 18:24 281 查看
前言: 之前见过瀑布流中的cell,由手势拖动变换位置的效果,一直觉得很炫很神奇。今天无意在破船之家看到了这种效果的实现方法。最核心的位置变换只需掉俩个方法,然后由系统完成。所以很简单,没有想象中的那么复杂。

我们先从简单的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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: