2013-02-14 24 views
41

UICollectionViewを使用してサムネイルのセットをすばやくスクロールしています。スクロールが終了すると、現在のサムネイルのより高解像度のバージョンを表示したいと思います。UICollectionView:スクロールが停止したときを検出する方法

ユーザーがスクロールを完了したときはどうすれば検出できますか?私はdidEndDisplayingCellを実装していますが、それは特定のセルがスクロールオフされたときにのみ通知します。スクロールモーションが実際に完了したときはわかりません。

答えて

97
NS_CLASS_AVAILABLE_IOS(6_0) @interface UICollectionView : UIScrollView 

UICollectionViewUIScrollViewのサブクラスです。したがって、代理人を設定してUIScrollViewDelegateを実装した場合は、UIScrollViewと同じ方法でこれを検出できるはずです。

例の場合

: - documentation 1として

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView; 

スクロールビューがスクロールの動きを減速終了したとき、上記の方法は教えてください。

+6

はブリリアント作ります。これでどれくらい厄介なコードが私を救ったのか分かりません。私は私のUICollectionViewFlowLayoutのshouldInvalidateLayoutForBoundsChangeコールバックを使用してそれを監視しようとしていました。どのようなn00b。 –

+0

scrollViewDidEndScrollingAnimationについては、下記のD6miの注を参照してください。 scrollViewDidEndDeceleratingは、プログラムによるスクロールのために呼び出されません。 – RajV

+1

実際、現在の回答が受け入れられた理由は分かりません。それは動作しません。scrollViewDidEndDeceleratingは呼び出されませんが、D6miのように、scrollViewDidEndScrollingAnimationが呼び出されました。 – AkademiksQc

44

あなたの拠点をカバーするだけで、これらの両方のUIScrollViewDelegateメソッドを実装する必要があります。 場合によっては、ページが完全に所定の位置にスクロールされているなど、減速していない可能性があります(また、scrollViewDidEndDeceleratingは呼び出されません)。その場合は、scrollViewDidEndDraggingにあなたのアップデートを行ってください。

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate 
{ 
    if (!decelerate) { 
    [self updateStuff]; 
    } 
} 

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 
{ 
    [self updateStuff]; 
} 
+6

ありがとうございます!これは受け入れられた回答でなければなりませんb/c OPは "スクロールが停止しました" - 両方のメソッドを使用しないと、ユーザは簡単にコレクションビューをスクロールして指を離すことができ、 'scrollViewDidEndDecelerating'は呼び出さず、scrollViewDidEndDragging' 。この回答を投稿していただきありがとうございます。 –

21

ここで注意すべき重要な事実:

をこの方法では、ユーザーが開始巻物(すなわちパンジェスチャー)一方

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView; 

に呼び出されますが、この1は、すべての上に呼び出されます手動で(プログラム的)( "でscrollRectToVisible" または "scrollToItemAtIndexPath" のような)スクロールを開始した

- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView 
4

スウィフト3バージョン:Abey MとD6miの回答の

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView 
{ 
    [self scrollingFinish]; 
} 
- (void)scrollingFinish { 


    if([self.collectionView indexPathsForVisibleSupplementaryElementsOfKind:UICollectionElementKindSectionHeader]){ 
     NSIndexPath *firstVisibleIndexPath = [[self.collectionView indexPathsForVisibleSupplementaryElementsOfKind:UICollectionElementKindSectionHeader] firstObject]; 
     [self.collectionView scrollToItemAtIndexPath:firstVisibleIndexPath atScrollPosition:UICollectionViewScrollPositionTop animated:YES]; 
     [NSObject cancelPreviousPerformRequestsWithTarget:self]; 
    } 
} 
+0

ありがとう!それはうまくいく。 – Raja

0

あなたは目に見えるindexpathを使用したい場合アクション

public func scrollViewDidEndDragging(_ scrollView: UIScrollView, willDecelerate decelerate: Bool) { 
    if (!decelerate) { 
     //cause by user 
     print("SCROLL scrollViewDidEndDragging") 
    } 
} 

public func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 
    //caused by user 
    print("SCROLL scrollViewDidEndDecelerating") 
} 

スクロールがコードアクションによって(プログラムによって)発生した場合:(「scrollRectToVisible」や「scrollT」など) oItemAtIndexPath ")

public func scrollViewDidEndScrollingAnimation(_ scrollView: UIScrollView) { 
    //caused by code 
    print("SCROLL scrollViewDidEndScrollingAnimation") 
} 

注:

  • あなたUIScrollViewDelegateやUICollectionViewDelegateデリゲートでこれらの関数を入れてください。あなたが別のデリゲートを持っていない場合
  • 、あなたの現在のクラスがあなたのクラスファイル

のUIScrollViewDelegateオペアンプトップを拡張します。

open class MyClass: NSObject , UICollectionViewDelegate 

とどこかにあなたのviewWillAppear内のクラス独自のデリゲート

override open func viewWillAppear(_ animated: Bool) { 
    super.viewWillAppear(animated) 
    // ... 
    self.myScrollView.delegate = self 
    // ... 
} 
1

スウィフト3バージョン:スクロールがユーザーによって引き起こされる

func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) { 
    // Your code here 
} 
関連する問題