LoginSignup
28
24

More than 5 years have passed since last update.

scrollViewDidScroll:が「呼ばれる」問題

Last updated at Posted at 2013-03-02

UITableViewのメソッドscrollToRowAtIndexPath:atScrollPosition:animated:は、最新のiOS 6.1 doc setによると、

Invoking this method does not cause the delegate to receive a scrollViewDidScroll: message, as is normal for programmatically-invoked user interface operations.

(拙訳) このメソッドを呼び出しても、通常のプログラマチックに呼び出されたユーザインタフェース操作のように、デリゲートはscrollViewDidScroll:メッセージを受け取りません。

と書いてありますが、実際には呼び出されてしまいます。
では、ユーザがTableViewをスクロールした時にだけ処理をしたい(したくない)! という時にはどうしたらいいのか。


ユーザがTableViewをスクロールする方法には(多分)二つあります。

  1. ビュー内部をドラッグする。
  2. ステータスバーをタップし、一番上までスクロールする。

このどちらかであることを検出できれば良い訳です。
もちろんサブクラス化してUIResponderのメソッドをオーバーライドしてもできますが、もうちょっと簡単な方法があります。

1についてはscrollViewDidScroll:内部でUIScrollViewのプロパティdraggingを調べることで検出します。
2については、スクロール直前に呼び出されるscrollViewShouldScrollToTop:と直後に呼び出されるscrollViewDidScrollToTop:でフラグを建てることで検出します。


こんな感じで実装します。

MyTableViewDelegate

@interface MyTableViewDelegate : NSObject <UITableViewDelegate>
@property (nonatomic) BOOL scrollingToTop;
@end


@implementation MyTableViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (scrollView.dragging || self.scrollingToTop) {
        ...
    }
}

- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView {
    self.scrollingToTop = YES;
    return YES;
}

- (void)scrollViewDidScrollToTop:(UIScrollView *)scrollView {
    self.scrollingToTop = NO;
}

@end

しかし、ドキュメントはしっかり書いてほしいものですね……

28
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
24