2009-08-27 12 views
10

私は、特定のUITableViewアニメーションの最後に反応して一連のことをしたいと思います。たとえば、scrollToRowAtIndexPathを使用してスクロールした後で、テーブルビューのセルを(selectRowAtIndexPathを使用して)強調表示します。UITableViewアニメーションがいつ完了するかを知るには?

どうすればいいですか?

答えて

-3

scrollToRowAtIndexPathが発生した後にアクションを実行したい場合は、

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

はあなたが置くことができる場所は、これらの以下のデリゲートメソッドは、アクティブにすべきか、ということ一旦自己

myAnimation.delegate = self; 

にdelgateを設定

CAAnimation *myAnimation; 

ようCAAnimationポインタを作成する必要がありますあなたのコード:

- (void)animationDidStart:(CAAnimation *)theAnimation 

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

どのようにあなたが 'myAnimation'ポインタを初期化していますか? –

27

基本テンプレート:

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

例:

[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を実行する方法"のために、はるかにクリーンな答えです。ありがとう! –

+1

このソリューションがiOS 4/5でどのように動作していたのか分かりませんが、現在iOS 6.1.4ではcontentOffsetがscrollToRowAtIndexPathによって変更された直後にこの位置のセルは表示されません数分の1秒でtableviewが完全に空白の場合、セルが描画され、キーボードが期待どおりに表示されます。私はUITableViewがこの方法で使用されることを意図していないか、少なくともiOSのこのバージョンでは使用されないと思います。同じ結果が、scrollToRowAtIndexPathの代わりにsetContentOffsetを使用して発生します。 – ggould75

+0

これは動作しているとは思わない – shim

2

I:終了したら、100行この行のセルを取得し、firstResponderにタグが付けられたセルコンテンツビュー= 1を作るためにスクロールこれは古い投稿であることを認識していますが、私は同様の問題を抱えていて、私にとってうまくいった解決策を作りました。私はNSCookBookで使用されているテクニックを適用して、ブロックを含むUIAlertViewsを作成しました。私がこれを行ったのは、UIViewの+ animateWithDuration:animations:completion:ではなく、組み込みのアニメーションを使用したかったからです。あなたがのUITableViewのために、あなたのテーブルビューのデリゲートとしてそれを割り当てることにより、ブロックをコールバックします内側のプライベートクラスを作成する実装ファイルでカテゴリを作成するiOSの7

に変更してこれらのアニメーションの間に大きな違いがあります。キャッチはブロックが呼び出されるまで元のデリゲートが「失われて」いるため、新しいデリゲートがブロックを呼び出すオブジェクトであるためです。そのため、元の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

+2

速記:スクロールビューが既に一番上にある場合、完了ブロックはトリガーしません。まず位置を確認する必要があります。 – Augie

+0

これは動作しますが、スクロール中またはスクロール後のheightForCellを無視しているようです。私は各セクションの下部に小さなセルを持っていますが、この方法は小さなセルを他のすべてと同じサイズにします。 – Darren