2012-03-27 41 views
25

我的iOS應用程序中有一個UITableView會定期刷新。用戶也可以隨時移動tableview行(tableview始終處於編輯模式)。如何獲得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 2012-09-07 11:21:37

+2

@mprudhom我收到回調,但他們沒有記錄。您是否在生產應用程序中使用這些委託方法?這是否被認爲是私人API? – Torsten 2012-10-31 11:42:39

+0

這些方法確實是在UITableView的委託上調用的。由於它們沒有記錄,Apple可能會在未來的iOS版本中打破它們,但從iOS 5到iOS 7,這仍然有效。 我還沒有發現蘋果是否真的允許將這些方法實現的應用程序發佈到App Store上(對我來說,祝你好運),但我不認爲有一個好的理由不會:如果我實現這3個方法在我的UIViewController中,並且它們沒有記錄,並且它們不以下劃線或其他方式開頭,它們與我自己的方法有什麼不同? – Argentumko 2013-11-02 10:54:43

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,如果蘋果改變其內部實現它仍可能會停止工作(即通過更改UITableViewCellReorderControl的類名)。

+0

感謝彼得,將需要重新思考我如果我當前的實現值得冒着依賴類名稱的風險,或者如果我更好地更改「tableview總是編輯」範例,以便在用戶進行編輯時我可以停止更新它。似乎更可靠,只是不知道如何將它集成到我的用戶界面中;) – Cornelius 2012-03-28 07:59:22

+0

這是公認的答案,因爲Apple添加並記錄了新的委託方法,所以將它改爲@mprudhom的答案。 – Cornelius 2015-03-09 16:05:21

+1

@Cornelius Apple在哪裏添加並記錄了新的委託方法?我在iOS 8上,他們仍然是私人API。 – 2015-03-21 12:57:57

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]; 
    } 
} 
相關問題