您的位置:首页 > 移动开发 > IOS开发

iOS tableViewCell 的移动操作 (添加长按手势)

2015-01-15 14:59 411 查看
     

                      


    本文借鉴于 Cookbook: Moving Table View Cells with a Long Press Gesture

来看一下我们都需要哪些准备工作?                                                                                                        

 UILongGestureRecognizer     长按手势                                                                  
 UITablveView (也可以是UICollectionView)
 UITableViewController (或者UIViewController、UICollectionViewController)

  1. 首先给tableView 添加一个 UILongGestureRecognizer手势,在这里我采用了UITableViewController,在ViewDIdLoad 方法中添加如下代码

      - (void)viewDidLoad
{
[super viewDidLoad];

// 数据源数组
for (int i = 0; i < 30; i++) {

[self.sources addObject:[NSString stringWithFormat:@"test item %d",i]];
}
UILongPressGestureRecognizer *longGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGesture:)];
[self.tableView addGestureRecognizer:longGesture];
}
 首先应该获取到在table view上长按的位置,然后找出和这个位置对应的cell的 indexPath .
- (void)longPressGesture:(UILongPressGestureRecognizer *)longGesture
{
CGPoint location = [longGesture locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
// 后续...
}  接着要处理 UIGestureRecognizerState 的began分支,如果indexPath 有效,就获取对应的UITableViewCell,并通过一个方法获取这个cell的snapshot view。
然后将这个snapshot view 添加到table view 中,并设置其center到对应的cell上。

 为了使移动效果看起来更自然,在这里使用了一个动画效果来增加snapshot view 的淡入效果。让它的y坐标偏移量与手势的位置的y对齐。这样设置之后,cell

就想从tablveView 中跳出,然后悬浮在上面,并捕捉到用户的手指。

static UIView *snapshot = nil;
static NSIndexPath *sourceIndexPath = nil;

switch (longGesture.state) {
case UIGestureRecognizerStateBegan:{
if (indexPath) {
sourceIndexPath = indexPath;
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
snapshot = [self customSnapsshotFromView:cell];
__block CGPoint center = cell.center;
snapshot.center = center;
snapshot.alpha = 0.0;
[self.tableView addSubview:snapshot];
[UIView animateWithDuration:0.2 animations:^{
center.y = location.y;
snapshot.center = center;
snapshot.alpha = 1.0;

} completion:nil];
}

}
break; 对应的customSnapsshotFromView:方法实现如下
- (UIView *)customSnapsshotFromView:(UIView *)inputView
{
UIView *snapShot;

if ([[UIDevice currentDevice].systemVersion floatValue]<7.0f) {

snapShot = [[UIView alloc]initWithFrame:inputView.frame];
// 1.开始上下文
UIGraphicsBeginImageContextWithOptions(inputView.bounds.size, YES, 1);
// 2.将view的图层渲染到上下文
[inputView.layer renderInContext:UIGraphicsGetCurrentContext()];
// 3.取出图片
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
// 4.结束上下文
UIGraphicsEndImageContext();
UIImageView *shot = [[UIImageView alloc]initWithImage:viewImage];
[snapShot addSubview:shot];
}
else {
// snapshotViewAfterScreenUpdates 此方法只在7.0以上才能使用
snapShot = [inputView snapshotViewAfterScreenUpdates:YES];
}
return snapShot;
}
 当手势移动的时候,也就是UIGestureRecognizerState 的Changed分支,需要移动snapshot view ,移动的位置到对应到另外一个indexPath后,需要做两项操作
 更新数据源,同时要移动 row  case UIGestureRecognizerStateChanged:{

CGPoint center = snapshot.center;
center.y = location.y;
snapshot.center = center;

if (indexPath && ![indexPath isEqual:sourceIndexPath]) {

// 改变数据源
[self.sources exchangeObjectAtIndex:indexPath.row withObjectAtIndex:sourceIndexPath.row];
// 移动cell
[self.tableView moveRowAtIndexPath:sourceIndexPath toIndexPath:indexPath];
sourceIndexPath = indexPath;
}
}
break;
  最后,当手势结束或着取消时,table view 和data source 都是最新的。这时所要做的事情只剩下把snapshot view 从table view中移除
default:{

UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:sourceIndexPath];
[UIView animateWithDuration:0.2 animations:^{
snapshot.center = cell.center;
snapshot.alpha = 0.0;
} completion:^(BOOL finished) {
[snapshot removeFromSuperview];
snapshot = nil;
}];
sourceIndexPath = nil;
}
break;


 这样,就搞定了。编译并运行程序,现在可以通过长按手势对tableView cell 重新排序了!
如何将其用在UICollectionView上?

 只需把之前的代码中的self.tableView 替换为self.collectionView ,并更新一下获取和移动UICollectionViewCell的调用方法。

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息