不要在特定位置使用长按手势移动表格视图单元格
Posted
技术标签:
【中文标题】不要在特定位置使用长按手势移动表格视图单元格【英文标题】:Don't Move Table View Cells with a Long Press Gesture on specific position 【发布时间】:2015-05-09 10:45:42 【问题描述】:我已经在我的应用程序中完全实现了 UILongGesture,它通过拖放来交换单元格值。现在我的要求是,如果我将第一行与最后一行一起移动,那么第一行应该保持在第一个位置意味着不想改变位置。
我尝试了一大堆代码并浪费了我的时间但无法获得结果。下面是我的代码。
- (IBAction)longPressGestureRecognized:(id)sender
UILongPressGestureRecognizer *longGesture = (UILongPressGestureRecognizer *)sender;
UIGestureRecognizerState state = longGesture.state;
CGPoint location = [longGesture locationInView:self.tblTableView];
NSIndexPath *indexpath = [self.tblTableView indexPathForRowAtPoint:location];
static UIView *snapshotView = nil;
static NSIndexPath *sourceIndexPath = nil;
switch (state)
case UIGestureRecognizerStateBegan:
if (indexpath)
sourceIndexPath = indexpath;
UITableViewCell *cell = [self.tblTableView cellForRowAtIndexPath:indexpath];
snapshotView = [self customSnapshotFromView:cell];
__block CGPoint center = cell.center;
snapshotView.center = center;
snapshotView.alpha = 0.0;
[self.tblTableView addSubview:snapshotView];
[UIView animateWithDuration:0.25 animations:^
center.y = location.y;
snapshotView.center = center;
snapshotView.transform = CGAffineTransformMakeScale(1.05, 1.05);
snapshotView.alpha = 0.98;
cell.alpha = 0.0;
completion:^(BOOL finished)
cell.hidden = YES;
];
break;
case UIGestureRecognizerStateChanged:
CGPoint center = snapshotView.center;
center.y = location.y;
snapshotView.center = center;
if (indexpath && ![NSIndexPath isEqual:sourceIndexPath])
[self.namesArray exchangeObjectAtIndex:indexpath.row withObjectAtIndex:sourceIndexPath.row];
[self.tblTableView moveRowAtIndexPath:sourceIndexPath toIndexPath:indexpath];
sourceIndexPath = indexpath;
NSIndexPath *indexPathOfLastItem =[NSIndexPath indexPathForRow:([self.namesArray count] - 1) inSection:0];
NSLog(@"last :::: %@",indexPathOfLastItem);
if (indexpath==indexPathOfLastItem)
[self.namesArray exchangeObjectAtIndex:indexPathOfLastItem.row withObjectAtIndex:sourceIndexPath.row];
[self.tblTableView moveRowAtIndexPath:indexPathOfLastItem toIndexPath:0];
UITableViewCell *cell = [self.tblTableView cellForRowAtIndexPath:sourceIndexPath];
cell.hidden = NO;
cell.alpha = 0.0;
break;
default:
UITableViewCell *cell = [self.tblTableView cellForRowAtIndexPath:sourceIndexPath];
cell.hidden = NO;
cell.alpha = 0.0;
[UIView animateWithDuration:0.25 animations:^
snapshotView.center = cell.center;
snapshotView.transform = CGAffineTransformIdentity;
snapshotView.alpha = 0.0;
cell.alpha = 1.0;
completion:^(BOOL finished)
sourceIndexPath = nil;
[snapshotView removeFromSuperview];
snapshotView = nil;
];
break;
编辑:我遇到的是细胞没有交换我想要的但它被隐藏了。这是图片:Image1 和 Image2
【问题讨论】:
if (indexpath && ![NSIndexPath isEqual:sourceIndexPath])
NSIndexPath
在那里做什么?似乎不对。也许,if (indexpath && ![indexpath isEqual:sourceIndexPath])
?
【参考方案1】:
首先,我认为您不应该在UIGestureRecognizerStateChanged
中进行行交换,而应在UIGestureRecognizerStateEnded
中进行。当您长按并在屏幕上移动手指时,UIGestureRecognizerStateChanged
会被快速处理(很多次)。所以这会导致行交换代码运行多次,我猜这不是你的意图。 UIGestureRecognizerStateBegan
和 UIGestureRecognizerStateEnded
每次长按运行一次。
我会将以下三行代码保留在UIGestureRecognizerStateChanged
中,并将其余代码移至UIGestureRecognizerStateEnded
:
CGPoint center = snapshotView.center;
center.y = location.y;
snapshotView.center = center;
UIGestureRecognizerState
s 如下:
UIGestureRecognizerStatePossible, // the recognizer has not yet recognized its gesture, but may be evaluating touch events. this is the default state
UIGestureRecognizerStateBegan, // the recognizer has received touches recognized as the gesture. the action method will be called at the next turn of the run loop
UIGestureRecognizerStateChanged, // the recognizer has received touches recognized as a change to the gesture. the action method will be called at the next turn of the run loop
UIGestureRecognizerStateEnded, // the recognizer has received touches recognized as the end of the gesture. the action method will be called at the next turn of the run loop and the recognizer will be reset to UIGestureRecognizerStatePossible
UIGestureRecognizerStateCancelled, // the recognizer has received touches resulting in the cancellation of the gesture. the action method will be called at the next turn of the run loop. the recognizer will be reset to UIGestureRecognizerStatePossible
UIGestureRecognizerStateFailed, // the recognizer has received a touch sequence that can not be recognized as the gesture. the action method will not be called and the recognizer will be reset to UIGestureRecognizerStatePossible
我相信在你的状态机逻辑中覆盖更多这些状态会更好,而不是使用switch
s default:
。
【讨论】:
我在 UIGestureRecognizerStateEnded 中尝试过,但没有任何效果。 Nij 你能把你的代码上传到 gitHub 并在这里发布 reprisotory 吗?这么多代码很难说清楚【参考方案2】:当你的手指在动画过程中离开屏幕时,ios 返回gesture.state = UIGestureRecognizerStatePossible
。
所以记得处理那个手势!
【讨论】:
以上是关于不要在特定位置使用长按手势移动表格视图单元格的主要内容,如果未能解决你的问题,请参考以下文章