65

ページにいくつかUIScrollViewあります。それらを個別にスクロールすることも、一緒にロックして 1 つとしてスクロールすることもできます。問題は、それらがロックされている場合に発生します。

と を使用UIScrollViewDelegatescrollViewDidScroll:て動きを追跡します。contentOffset変更されたのをクエリし、プロパティを一致するようにUIScrollView設定して、変更を他のスクロール ビューに反映します。contentOffset

すばらしい....ただし、余分な呼び出しがたくさんあることに気づきました。プログラムcontentOffsetでスクロール ビューを変更すると、デリゲート メソッドscrollViewDidScroll:が呼び出されます。setContentOffset:animated:代わりに使用してみましたが、まだデリゲートでトリガーを取得しています。

トリガーしないように contentOffsets をプログラムで変更するにはどうすればよいscrollViewDidScroll:ですか?

実装に関する注意事項....それぞれは、デリゲート パターンを使用して、さまざまな値の調整を処理する提示サブクラスにコールバックするUIScrollViewカスタムの一部です。UIViewUIViewControllercontentOffset

4

6 に答える 6

111

目的のコンテンツ オフセットに設定された原点を使用しての境界を設定することによりUIScrollView、デリゲート コールバックをトリガーせずに のコンテンツ オフセットを変更することができます。scrollViewDidScroll:UIScrollView

CGRect scrollBounds = scrollView.bounds;
scrollBounds.origin = desiredContentOffset;
scrollView.bounds = scrollBounds;
于 2012-02-23T18:05:05.487 に答える
82

試す

id scrollDelegate = scrollView.delegate;
scrollView.delegate = nil;
scrollView.contentOffset = point;
scrollView.delegate = scrollDelegate;

私のために働いた。

于 2013-07-25T11:10:25.113 に答える
56

UIScrollView の既存のプロパティを使用するのはどうですか?

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if (scrollView.isTracking || scrollView.isDragging || scrollView.isDecelerating) {
        /// The content offset was changed programmatically.
        /// Your code goes here.
    }
}
于 2014-11-08T16:35:08.197 に答える
6

@Tarkの答えを単純化すると、次のscrollViewDidScrollように1行で起動せずにスクロールビューを配置できます。

scrollView.bounds.origin = CGPoint(x:0, y:100); // whatever values you'd like
于 2015-03-10T12:33:09.093 に答える
4

これは質問に対する直接的な回答ではありませんが、そのような偽のメッセージのように見えるものを受け取っている場合は、境界を変更していることが原因である可能性もあります。サブビューを削除してスクロールビューに追加する「tilePages」メソッドでいくつかのAppleサンプルコードを使用しています。これにより、追加の scrollViewDidScroll: メッセージがすぐに呼び出されることがまれに発生するため、予期しない再帰が発生します。私の場合、クラッシュを見つけることが不可能になりました。

私がやったことは、メインキューで呼び出しをキューに入れることでした:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    if(scrollView == yourScrollView) {
        // dispatch fixes some recursive call to scrollViewDidScroll in tilePages (related to removeFromSuperView)
        // The reason can be found here: http://stackoverflow.com/questions/9418311
        dispatch_async(dispatch_get_main_queue(), ^{ [self tilePages]; });
    }
}
于 2012-03-31T21:00:26.347 に答える