web-dev-qa-db-ja.com

UICollectionViewのスクロールをリセット

正常に動作し、スクロールする水平UICollectionViewがあります。アイテムをタップすると、データを更新してreloadDataを呼び出します。これは機能し、新しいデータがUICollectionViewに表示されます。問題は、スクロール位置が変わらず、最後の場所がまだ表示されていることです。スクロールを一番上にリセットしたい(または私の場合は左にしたい)。これどうやってするの?

47
MulletDevil

このメソッドを使用して、必要な項目にスクロールできます。

- (void)scrollToItemAtIndexPath:(NSIndexPath *)indexPath 
               atScrollPosition:(UICollectionViewScrollPosition)scrollPosition 
                       animated:(BOOL)animated
30
Nils Hott

setContentOffset:。 CGPointMakeを使用して必要なものに設定できる引数としてCGPointを使用しますが、コレクションの最初に戻りたい場合は、CGPointZeroを使用するだけです。

[collectionView setContentOffset:CGPointZero animated:YES];
160
Mick MacCallum

私はこれをアプリのさまざまな部分で頻繁に使用するため、UIScrollViewを拡張して、任意のスクロールビューおよびスクロールビューサブクラスで使用できるようにしました。

extension UIScrollView {        
    /// Sets content offset to the top.
    func resetScrollPositionToTop() {
        self.contentOffset = CGPoint(x: -contentInset.left, y: -contentInset.top)
    }
}

だから私は位置をリセットする必要があるときはいつでも:

self.collectionView.resetScrollPositionToTop()
19
Daniel Galasko

Swiftの場合:

collectionView.setContentOffset(CGPointZero, animated: true)

コレクションビューを含むビューを離れる場合、2番目のView Controllerで変更を行い、戻ったときにコレクションビューを更新する必要があります。

@IBAction func unwindTo_CollectionViewVC(segue: UIStoryboardSegue) {
    //Automatic table reload upon unwind
    viewDidLoad()
    collectionView.reloadData()
    collectionView.setContentOffset(CGPointZero, animated: true)
}

私の状況では、viewDidLoad呼び出しがCoreDataコンテキストを更新し、reloadData呼び出しがcollectionViewが新しいCoreDataコンテキストを反映するように更新し、contentOffsetがテーブルが先頭に戻ることを確認するため、巻き戻しは素晴らしいです。

12
Dave G

私の場合、CGPointZeroはコレクションビューのコンテンツをシフトしました。これは、コンテンツのインセットをカウントしないためです。これは私のために働いたものです:

    CGPoint topOffest = CGPointMake(0,-self.collectionView.contentInset.top);
    [self.collectionView setContentOffset:topOffest animated:YES];

この記事を書いている時点ではコメントできませんでしたが、UINavigationControllerを使用していたので、CGPointZero自体が最上部に到達しなかったため、代わりに次のものを使用する必要がありました。

CGFloat compensateHeight = -(self.navigationController.navigationBar.bounds.size.height+[UIApplication sharedApplication].statusBarFrame.size.height);
[self.collectionView setContentOffset:CGPointMake(0, compensateHeight) animated:YES];

これが将来誰かに役立つことを願っています。乾杯!

4
Ryan

コントローラーに安全な領域が含まれている場合、コード:

collectionView.setContentOffset(CGPointZero, animated: true)

動作しないため、ユニバーサル拡張機能を使用できます。

extension UIScrollView {
    func scrollToTop(_ animated: Bool) {
        var topContentOffset: CGPoint
        if #available(iOS 11.0, *) {
            topContentOffset = CGPoint(x: -safeAreaInsets.left, y: -safeAreaInsets.top)
        } else {
            topContentOffset = CGPoint(x: -contentInset.left, y: -contentInset.top)
        }
        setContentOffset(topContentOffset, animated: animated)
    }
}
3
Alexander

UINavigationControllerと透明なナビゲーションバーを扱うには、最初の要素の位置に完全に一致するように余分な上部オフセットを計算する必要がありました。

Swift 1.1コード:

     let topOffest = CGPointMake(0, -(self.collectionView?.contentInset.top ?? O))
     self.collectionView?.setContentOffset(topOffest, animated: true)

乾杯!

2
Kevin Delord
  • Swift 4.2ソリューション-各tableViewCellにHorizo​​ntalCollectionViewが含まれるtableViewがあるとします。セルを再利用するため、最初のtableViewCellがページ4に下にスクロールされても、他のセルもページ4に設定されます。

これはこのような場合に機能します-tableViewのcellForRowAt funcで、cell = // deque cell.myCollectionView.contentOffset = CGPoint(x:0、y:0)を使用してセルを宣言します

0
Sak