2009-08-27 43 views
10

我想對某些UITableView動畫的結尾做一系列反應。例如,我希望表格視圖單元格通過scrollToRowAtIndexPath滾動後突出顯示(通過selectRowAtIndexPath)。如何知道UITableView動畫何時完成?

這怎麼辦?

回答

-3

那麼如果你想在scrollToRowAtIndexPath被觸發時執行一個動作。

- (void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath atScrollPosition:(UITableViewScrollPosition)scrollPosition animated:(BOOL)animated 

你需要創建一個CAAnimation指針像

CAAnimation *myAnimation; 

然後delgate設置爲自

myAnimation.delegate = self; 

一旦你這樣做,這些下面的委託方法應該啓動,你可以把您的代碼:

- (void)animationDidStart:(CAAnimation *)theAnimation 

- (void)animationDidStop:(CAAnimation *)theAnimation finished:(BOOL)flag 
+5

你是如何初始化你的'myAnimation'指針? – 2011-09-01 22:11:25

27

基本模板:

[UIView animateWithDuration:0.2 animations:^{ 
    //do some animations, call them with animated:NO 
} completion:^(BOOL finished){ 
    //Do something after animations finished  
}]; 

示例:滾動到行100完成後,在該行獲得的細胞,並與標籤單元格內容視圖= 1至firstResponder:

[UIView animateWithDuration:0.2 animations:^{ 
     [self.tableView scrollToRowAtIndexPath:[NSIndexPath indexPathForRow:100 inSection:0] atScrollPosition:UITableViewScrollPositionTop animated:NO]; 
    } completion:^(BOOL finished){ 
     //Do something after scrollToRowAtIndexPath finished, e.g.: 
     UITableViewCell *nextCell = [self.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:100 inSection:0]]; 
     [[nextCell.contentView viewWithTag:1] becomeFirstResponder];   
    }]; 
+0

這是迄今爲止對於「在scrollToRowAtIndexPath完成後如何執行X」的最清晰的答案?謝謝! – 2013-02-26 10:25:00

+1

我不知道這個解決方案如何在iOS 4/5上工作,但現在在iOS 6.1.4上,我注意到contentOffset被scrollToRowAtIndexPath更改後,這個位置的單元格不可見,所以對於第二個tableview的分數是完全空白的,然後繪製單元格並按預期顯示鍵盤。我猜UITableView並不是用於這種方式,或者至少不是在這個版本的iOS中。使用setContentOffset而不是scrollToRowAtIndexPath可以得到相同的結果。 – ggould75 2013-05-23 10:38:43

+0

我不認爲這是可行的 – shim 2013-07-03 03:37:25

2

我意識到這是一箇舊帖子,但我遇到了類似的問題,並創建了一個適用於我的解決方案。我將NSCookBook上使用的技術用於創建帶有塊的UIAlertView。我之所以這樣做是因爲我想使用內置的動畫而不是UIView的+ animateWithDuration:動畫:completion :.這些動畫與iOS 7的更改有較大的區別。

您爲UITableView創建一個類別,並在實現文件中創建一個內部私有類,該類將通過將其分配爲您的tableview委託來回調該塊。可以肯定的是,在塊被調用之前,原來的委託將會「丟失」,因爲新委託是調用塊的對象。這就是爲什麼當調用塊重新分配原始UITableViewDelegate時,我會通知發送消息。這段代碼已經過測試,並且正在處理我的工作。

// Header file 
@interface UITableView (ScrollDelegateBlock) 

-(void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath 
      atScrollPosition:(UITableViewScrollPosition)scrollPosition 
        animated:(BOOL)animated 
       scrollFinished:(void (^)())scrollFinished; 

@end 


// Implementation file 
#import "UITableView+ScrollDelegateBlock.h" 
#import <objc/runtime.h> 

NSString *const BLOCK_CALLED_NOTIFICATION = @"BlockCalled"; 

@interface ScrollDelegateWrapper : NSObject <UITableViewDelegate> 

@property (copy) void(^scrollFinishedBlock)(); 

@end 

@implementation ScrollDelegateWrapper 

-(void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView { 
    if (self.scrollFinishedBlock) { 
     [[NSNotificationCenter defaultCenter] postNotificationName:BLOCK_CALLED_NOTIFICATION object:nil]; 
     self.scrollFinishedBlock(); 
    } 
} 

@end 

static const char kScrollDelegateWrapper; 

static id<UITableViewDelegate>previousDelegate; 

@implementation UITableView (ScrollDelegateBlock) 

-(void)scrollToRowAtIndexPath:(NSIndexPath *)indexPath 
      atScrollPosition:(UITableViewScrollPosition)scrollPosition 
        animated:(BOOL)animated 
       scrollFinished:(void (^)())scrollFinished { 
    previousDelegate = self.delegate; 
    ScrollDelegateWrapper *scrollDelegateWrapper = [[ScrollDelegateWrapper alloc] init]; 
    scrollDelegateWrapper.scrollFinishedBlock = scrollFinished; 
    self.delegate = scrollDelegateWrapper; 

    objc_setAssociatedObject(self, &kScrollDelegateWrapper, scrollDelegateWrapper, OBJC_ASSOCIATION_RETAIN_NONATOMIC); 

    [self scrollToRowAtIndexPath:indexPath atScrollPosition:scrollPosition animated:animated]; 

    [[NSNotificationCenter defaultCenter] addObserver:self 
              selector:@selector(blockCalled:) 
               name:BLOCK_CALLED_NOTIFICATION 
               object:nil]; 
} 

/* 
* Assigns delegate back to the original delegate 
*/ 
-(void) blockCalled:(NSNotification *)notification { 
    self.delegate = previousDelegate; 
    [[NSNotificationCenter defaultCenter] removeObserver:self 
                name:BLOCK_CALLED_NOTIFICATION 
                object:nil]; 
} 

@end 

然後,您可以調用像任何其他與塊的方法:

[self.tableView scrollToRowAtIndexPath:self.currentPath 
          atScrollPosition:UITableViewScrollPositionMiddle 
            animated:YES 
          scrollFinished:^{ 
           NSLog(@"scrollFinished"); 
          } 
]; 
+0

感謝您發佈此信息。將其轉換爲我的收藏視圖並且工作完美。 – Augie 2013-11-08 14:14:10

+2

快速提示:如果滾動視圖已位於頂部,則完成塊不會觸發。需要先檢查位置。 – Augie 2013-11-08 15:35:15

+0

這是有效的,但它似乎忽略了scrollFor期間/之後的heightForCell。我在每個部分的底部都有一個較小的單元格,但是這種方法使得較小的單元格與所有其他單元格的大小相同。 – Darren 2015-01-13 12:29:54

相關問題