2012-03-27 3 views
25

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

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

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

Спасибо!

ответ

34

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

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

Я не вижу этих методов делегатов, объявленных в интерфейсе UITableView.h. Не могли бы вы объяснить, где мы можем их найти? – imnk

+2

@mprudhom Я получил обратные вызовы, но они недокументированы. У вас есть эти методы делегата в производственном приложении? Является ли это частным API? – Torsten

+0

Эти методы действительно вызываются делегатом UITableView. Поскольку они недокументированы, Apple может просто сломать их в будущих выпусках iOS, но с iOS 5 и до iOS 7 это все еще работает. Мне еще предстоит выяснить, сможет ли Apple разрешить приложение с такими методами, которые будут опубликованы в App Store (удачи мне, я думаю), но я не думаю, что есть веская причина не делать этого: если я реализую эти 3 метода в моем UIViewController, и они не документированы, и они не начинаются с подчеркивания или что-то еще, как они отличаются от моих собственных методов? – Argentumko

9

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

Вкратце: вам необходимо создать собственный подкласс 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).

+0

Спасибо, Питер, нужно будет переосмыслить i f моя текущая реализация стоит риск полагаться на имя класса, или если мне лучше изменить парадигму «tableview is always editing», чтобы я мог перестать ее обновлять, как только пользователь редактирует редактирование. Кажется более надежным, просто не уверен, как интегрировать его в моем пользовательском интерфейсе;) – Cornelius

+0

Это был принятый ответ, заменивший его на ответ от @mprudhom, так как Apple добавила и задокументировала новые методы делегата. – Cornelius

+1

@Cornelius Где Apple добавила и задокументировала новые методы делегата? Я нахожусь на iOS 8, и они по-прежнему являются частным API. –

0

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

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

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

@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]; 
    } 
} 
Смежные вопросы