Как получить уведомление о начале и конце перемещения UITableViewCell?

У меня в приложении для iOS есть UITableView, который периодически обновляется. Пользователь также может перемещать строки таблицы в любое время (таблица всегда находится в режиме редактирования).

Я хочу остановить таймер обновления, когда пользователь начинает перетаскивать строку, и запускать его снова, когда строка удаляется.

Последняя часть должна быть легкой с moveRowAtIndexPath, но как получить уведомление о начале перетаскивания?

Ответ 1

Ваш UITableViewDelegate получит следующие уведомления в ответ на действия переупорядочения:

- (void)tableView:(UITableView *)tableView willBeginReorderingRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didEndReorderingRowAtIndexPath:(NSIndexPath *)indexPath;
- (void)tableView:(UITableView *)tableView didCancelReorderingRowAtIndexPath:(NSIndexPath *)indexPath;

Ответ 2

Я столкнулся с той же проблемой некоторое время назад и не нашел решения. В то время как я начал этот ответ с объяснения, почему это не может быть сделано, я действительно узнал, как это можно сделать!: -)

Вкратце: вам нужно создать собственный подкласс UITableViewCell. Переопределите layoutSubviews, чтобы добавить UILongPressGestureRecognizer в UITableViewCellReorderControl. Определите протокол и используйте делегат, чтобы сообщить кому бы вы ни говорили о состоянии перетаскивания.

CustomTableViewCell.h:

#import <UIKit/UIKit.h>

@protocol CustomTableViewCellDelegate;

@interface CustomTableViewCell : UITableViewCell {
}

@property (nonatomic, assign) id <CustomTableViewCellDelegate> delegate;

@end

@protocol CustomTableViewCellDelegate
- (void)CustomTableViewCell:(CustomTableViewCell *)cell isDragging:(BOOL)value;
@end

CustomTableViewCell.m:

#import "CustomTableViewCell.h"

@implementation CustomTableViewCell

@synthesize delegate = _delegate;

- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer {
    if (gestureRecognizer.state == UIGestureRecognizerStateBegan) {
        [_delegate CustomTableViewCell:self isDragging:YES];    // Dragging started
    } else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) {
        [_delegate CustomTableViewCell:self isDragging:NO];     // Dragging ended
    }
}

- (void)layoutSubviews {
    [super layoutSubviews];

    for (UIView *view in self.subviews) {
        if ([NSStringFromClass ([view class]) rangeOfString:@"ReorderControl"].location != NSNotFound) {    // UITableViewCellReorderControl
            if (view.gestureRecognizers.count == 0) {
                UILongPressGestureRecognizer *gesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
                gesture.cancelsTouchesInView    = NO;
                gesture.minimumPressDuration    = 0.150;
                [view addGestureRecognizer:gesture];
            }
        }
    }
}

@end

Помните, что, хотя этот код не использует какие-либо частные API, он все равно может перестать работать, если Apple изменит внутреннюю реализацию (т.е. изменив имя класса UITableViewCellReorderControl).

Ответ 3

Просто я нашел хак, так как яблоко уменьшит альфу, мы можем использовать это, я думаю

@interface CustomTableViewCell () 
@property (nonatomic, assign) BOOL isDragging;
@end

-(void)draggingWillBegan
{
    //use a delegate method to inform tableview
}

-(void)draggingDidEnd
{
    //use a delegate method to inform tableview
}

- (void)layoutSubviews
{
    [super layoutSubviews];

    //Since apple wont provide en
    if(self.alpha <= 0.95 && !self.isDragging){
        self.isDragging = YES;
        [self draggingWillBegan];
    }

    if(self.alpha >= 0.95 && self.isDragging){
        self.isDragging = NO;
        [self draggingDidEnd];
    }
}

Ответ 4

этот метод вызывается, когда вы закончите перемещение ячеек:

- (void) tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)sourceIndexPath toIndexPath:(NSIndexPath *)destinationIndexPath