利用长按手势移动TableView中的Cell
2015-05-28 20:03
453 查看
需要什么?
UILongGestureRecognizer
UITableView(可以用UICollectionView代替)
UITableViewController(可以用UIViewController 或 UICollectionViewController)
首先给 table view 添加一个
table view controller 的
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(longPressGestureRecognized:)];
[self.tableView addGestureRecognizer:longPress];
为 gesture recognizer
添加 action 方法。该方法首先应该获取到在 table view 中长按的位置,然后找出这个位置对应的 cell 的 index。记住:这里获取到的 index path 有可能为 nil(例如,如果用户长按在 table view的section header上)。
- (IBAction)longPressGestureRecognized:(id)sender {
UILongPressGestureRecognizer *longPress = (UILongPressGestureRecognizer *)sender;
UIGestureRecognizerState state = longPress.state;
CGPoint location = [longPress locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
// More coming soon...
}
接着你需要处理
的 snapshot view。然后将这个 snapshot view 添加到 table view 中,并将其 center 到对应的 cell上。
为了更好的用户体验,以及更自然的效果,在这里我把原始 cell 的背景设置为黑色,并给 snapshot view 增加淡入效果,让 snapshot view 比 原始 cell 稍微大一点,将它的Y坐标偏移量与手势的位置的Y轴对齐。这样处理之后,cell 就像从 table view 中跳出,然后浮在上面,并捕捉到用户的手指。
static UIView *snapshot = nil; ///< A snapshot of the row user is moving.
static NSIndexPath *sourceIndexPath = nil; ///< Initial index path, where gesture begins.
switch (state) {
case UIGestureRecognizerStateBegan: {
if (indexPath) {
sourceIndexPath = indexPath;
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
// Take a snapshot of the selected row using helper method.
snapshot = [self customSnapshotFromView:cell];
// Add the snapshot as subview, centered at cell's center...
__block CGPoint center = cell.center;
snapshot.center = center;
snapshot.alpha = 0.0;
[self.tableView addSubview:snapshot];
[UIView animateWithDuration:0.25 animations:^{
// Offset for gesture location.
center.y = location.y;
snapshot.center = center;
snapshot.transform = CGAffineTransformMakeScale(1.05, 1.05);
snapshot.alpha = 0.98;
// Black out.
cell.backgroundColor = [UIColor blackColor];
} completion:nil];
}
break;
}
// More coming soon...
}
将下面的方法添加到 .m 文件的尾部。该方法会根据传入的 view,返回一个对应的 snapshot view。
- (UIView *)customSnapshotFromView:(UIView *)inputView {
UIView *snapshot = [inputView snapshotViewAfterScreenUpdates:YES];
snapshot.layer.masksToBounds = NO;
snapshot.layer.cornerRadius = 0.0;
snapshot.layer.shadowOffset = CGSizeMake(-5.0, 0.0);
snapshot.layer.shadowRadius = 5.0;
snapshot.layer.shadowOpacity = 0.4;
return snapshot;
}
当手势移动的时候,也就是
snapshot view(只需要设置它的 Y 轴偏移量即可)。如果手势移动的距离对应到另外一个 index path,就需要告诉 table view,让其移动 rows。同时,你需要对 data source 进行更新:
case UIGestureRecognizerStateChanged: {
CGPoint center = snapshot.center;
center.y = location.y;
snapshot.center = center;
// Is destination valid and is it different from source?
if (indexPath && ![indexPath isEqual:sourceIndexPath]) {
// ... update data source.
[self.objects exchangeObjectAtIndex:indexPath.row withObjectAtIndex:sourceIndexPath.row];
// ... move the rows.
[self.tableView moveRowAtIndexPath:sourceIndexPath toIndexPath:indexPath];
// ... and update source so it is in sync with UI changes.
sourceIndexPath = indexPath;
}
break;
}
// More coming soon...
最后,当手势结束或者取消时,table view 和 data source 都是最新的。你所需要做的事情就是将 snapshot view 从 table view 中移除,并把 cell 的背景色还原为白色。
为了提升用户体验,我们将 snapshot view 淡出,并让其尺寸变小至与 cell 一样。这样看起来就像把 cell 放回原处一样。
default: {
// Clean up.
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:sourceIndexPath];
[UIView animateWithDuration:0.25 animations:^{
snapshot.center = cell.center;
snapshot.transform = CGAffineTransformIdentity;
snapshot.alpha = 0.0;
// Undo the black-out effect we did.
cell.backgroundColor = [UIColor whiteColor];
} completion:^(BOOL finished) {
[snapshot removeFromSuperview];
snapshot = nil;
}];
sourceIndexPath = nil;
break;
}
就这样,搞定了!编译并运行程序,现在可以通过长按手势对 tableview cells重新排序!
如何将其利用至UICollectionView上?
假设你已经有一个示例工程使用了
转自:破船的博客
原文地址:http://ios.9tech.cn/news/2014/0328/40129.html
UILongGestureRecognizer
UITableView(可以用UICollectionView代替)
UITableViewController(可以用UIViewController 或 UICollectionViewController)
首先给 table view 添加一个
UILongGestureRecognizer。可以在
table view controller 的
viewDidLoad方法中添加。
UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]
initWithTarget:self action:@selector(longPressGestureRecognized:)];
[self.tableView addGestureRecognizer:longPress];
为 gesture recognizer
添加 action 方法。该方法首先应该获取到在 table view 中长按的位置,然后找出这个位置对应的 cell 的 index。记住:这里获取到的 index path 有可能为 nil(例如,如果用户长按在 table view的section header上)。
- (IBAction)longPressGestureRecognized:(id)sender {
UILongPressGestureRecognizer *longPress = (UILongPressGestureRecognizer *)sender;
UIGestureRecognizerState state = longPress.state;
CGPoint location = [longPress locationInView:self.tableView];
NSIndexPath *indexPath = [self.tableView indexPathForRowAtPoint:location];
// More coming soon...
}
接着你需要处理
UIGestureRecognizerStateBegan分支。如果获取到一个有效的 index path(non-nil),就去获取对应的
UITableViewCell,并利用一个 helper 方法获取这个 table view cell
的 snapshot view。然后将这个 snapshot view 添加到 table view 中,并将其 center 到对应的 cell上。
为了更好的用户体验,以及更自然的效果,在这里我把原始 cell 的背景设置为黑色,并给 snapshot view 增加淡入效果,让 snapshot view 比 原始 cell 稍微大一点,将它的Y坐标偏移量与手势的位置的Y轴对齐。这样处理之后,cell 就像从 table view 中跳出,然后浮在上面,并捕捉到用户的手指。
static UIView *snapshot = nil; ///< A snapshot of the row user is moving.
static NSIndexPath *sourceIndexPath = nil; ///< Initial index path, where gesture begins.
switch (state) {
case UIGestureRecognizerStateBegan: {
if (indexPath) {
sourceIndexPath = indexPath;
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:indexPath];
// Take a snapshot of the selected row using helper method.
snapshot = [self customSnapshotFromView:cell];
// Add the snapshot as subview, centered at cell's center...
__block CGPoint center = cell.center;
snapshot.center = center;
snapshot.alpha = 0.0;
[self.tableView addSubview:snapshot];
[UIView animateWithDuration:0.25 animations:^{
// Offset for gesture location.
center.y = location.y;
snapshot.center = center;
snapshot.transform = CGAffineTransformMakeScale(1.05, 1.05);
snapshot.alpha = 0.98;
// Black out.
cell.backgroundColor = [UIColor blackColor];
} completion:nil];
}
break;
}
// More coming soon...
}
将下面的方法添加到 .m 文件的尾部。该方法会根据传入的 view,返回一个对应的 snapshot view。
- (UIView *)customSnapshotFromView:(UIView *)inputView {
UIView *snapshot = [inputView snapshotViewAfterScreenUpdates:YES];
snapshot.layer.masksToBounds = NO;
snapshot.layer.cornerRadius = 0.0;
snapshot.layer.shadowOffset = CGSizeMake(-5.0, 0.0);
snapshot.layer.shadowRadius = 5.0;
snapshot.layer.shadowOpacity = 0.4;
return snapshot;
}
当手势移动的时候,也就是
UIGestureRecognizerStateChanged分支,此时需要移动
snapshot view(只需要设置它的 Y 轴偏移量即可)。如果手势移动的距离对应到另外一个 index path,就需要告诉 table view,让其移动 rows。同时,你需要对 data source 进行更新:
case UIGestureRecognizerStateChanged: {
CGPoint center = snapshot.center;
center.y = location.y;
snapshot.center = center;
// Is destination valid and is it different from source?
if (indexPath && ![indexPath isEqual:sourceIndexPath]) {
// ... update data source.
[self.objects exchangeObjectAtIndex:indexPath.row withObjectAtIndex:sourceIndexPath.row];
// ... move the rows.
[self.tableView moveRowAtIndexPath:sourceIndexPath toIndexPath:indexPath];
// ... and update source so it is in sync with UI changes.
sourceIndexPath = indexPath;
}
break;
}
// More coming soon...
最后,当手势结束或者取消时,table view 和 data source 都是最新的。你所需要做的事情就是将 snapshot view 从 table view 中移除,并把 cell 的背景色还原为白色。
为了提升用户体验,我们将 snapshot view 淡出,并让其尺寸变小至与 cell 一样。这样看起来就像把 cell 放回原处一样。
default: {
// Clean up.
UITableViewCell *cell = [self.tableView cellForRowAtIndexPath:sourceIndexPath];
[UIView animateWithDuration:0.25 animations:^{
snapshot.center = cell.center;
snapshot.transform = CGAffineTransformIdentity;
snapshot.alpha = 0.0;
// Undo the black-out effect we did.
cell.backgroundColor = [UIColor whiteColor];
} completion:^(BOOL finished) {
[snapshot removeFromSuperview];
snapshot = nil;
}];
sourceIndexPath = nil;
break;
}
就这样,搞定了!编译并运行程序,现在可以通过长按手势对 tableview cells重新排序!
如何将其利用至UICollectionView上?
假设你已经有一个示例工程使用了
UICollectionView,那么你可以很简单的就使用上本文之前介绍的代码。所需要做的事情就是用
self.collectionView替换掉
self.tableView,并更新一下获取和移动
UICollectionViewCell的调用方法。
转自:破船的博客
原文地址:http://ios.9tech.cn/news/2014/0328/40129.html
相关文章推荐
- 利用长按手势移动 Table View Cells
- iOS 利用长按手势移动 Table View Cells
- 利用长按手势移动 Table View Cells
- 利用长按手势移动 Table View Cells
- 利用长按手势移动 Table View Cells
- tableView上添加手势 & 在cell 上添加快捷菜单
- tableview cell的移动
- 防止TableView 上的tap手势隔断 cell的选择
- 【iOS开发-68】APP下载案例:利用tableView自带的cell布局+缓存池cell复用时注意按钮状态的检查
- tableView section随cell移动 ,不在顶到屏幕顶部
- tableView中cell的删除、插入、移动、复制粘贴问题详解代码分析
- IOS——TableView 中利用Item模型进行 Cell 的开发(2)Item 模型篇
- iOS tableView 的 cell上其它控件重用(利用view的tag属性巧妙实现重用,从xib中加在cell重载问题)
- iOS 开发,UITableViewController中手势关闭cell中的键盘。且不影响tableView中的 didSelectRowAtIndexPath 方法。
- SWTableView(CCTableView)移动列表项到指定索引对应的cell
- tableView左滑删除,自定义标题+cell长按手势
- SWTableView(CCTableView)移动列表项到指定索引对应的cell
- view添加手势与tableView的cell点击冲突问题
- IOS 构造和使用TableView(基于storyboard) (七)移动cell和section