Не перемещайте ячейки табличного вида с помощью длинного нажатия на конкретную позицию
Я полностью реализовал 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
2 ответа
Когда ваш палец отсоединяется от экрана во время анимации, iOS возвращается gesture.state = UIGestureRecognizerStatePossible
,
Так что не забудьте обработать этот жест!
Прежде всего, я не думаю, что вы должны делать обмен строк в 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:
Я верю, что будет лучше охватить больше этих состояний в логике вашей машины состояний.