web-dev-qa-db-ja.com

UICollectionViewはIndexPathのセルに自動スクロールします

コレクションビューを読み込む前に、ユーザーはコレクションビューの配列に画像の数を設定します。すべてのセルが画面に収まりません。画面には30個のセルがあり、6個しかありません。

質問:UICollectionViewのロード時に、目的の画像を含むセルに自動的にスクロールする方法は?

90
AlexanderZ

コレクションビューがまだレイアウトを完了していないため、viewWillAppearでのスクロールが確実に機能しないことがあります。間違ったアイテムにスクロールする可能性があります。

viewDidAppearをスクロールすると、スクロールされていないビューの瞬間的なフラッシュが表示されることもわかりました。

また、viewDidLayoutSubviewsを毎回スクロールすると、コレクションレイアウトによってはスクロールするたびにサブビューレイアウトが発生するため、ユーザーは手動でスクロールできません。

私が見つけたものは確実に動作します:

- (void)viewDidLayoutSubviews {
    [super viewDidLayoutSubviews];

    // If we haven't done the initial scroll, do it once.
    if (!self.initialScrollDone) {
        self.initialScrollDone = YES;

        [self.collectionView scrollToItemAtIndexPath:self.myInitialIndexPath
                                    atScrollPosition:UICollectionViewScrollPositionRight animated:NO];
    }
}
76
LenK

新規、編集済み回答:

これをviewDidLayoutSubviewsに追加します

スイフト

override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    let indexPath = IndexPath(item: 12, section: 0)
    self.collectionView.scrollToItem(at: indexPath, at: [.centeredVertically, .centeredHorizontally], animated: true)
}

通常、.centerVerticallyが該当します

ObjC

-(void)viewDidLayoutSubviews {
   [super viewDidLayoutSubviews];
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:12 inSection:0];
   [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically | UICollectionViewScrollPositionCenteredHorizontally animated:NO];
}

古いiOSで機能する古い回答

これをviewWillAppearに追加します。

[self.view layoutIfNeeded];
[self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:NO];
160
boweidmann

上記の答えに完全に同意します。唯一のことは、私にとって解決策はviewDidAppearのコードを設定したことです

viewDidAppear 
{
    [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredVertically animated:YES];
}

ViewWillAppearを使用したときに、スクロールが機能しませんでした。

13
raistlin

スイフト:

your_CollectionView.scrollToItemAtIndexPath(indexPath, atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: true)

Swift

let indexPath = IndexPath(row: itemIndex, section: sectionIndex)

collectionView.scrollToItem(at: indexPath, at: UICollectionViewScrollPosition.right, animated: true)

スクロール位置:

UICollectionViewScrollPosition.CenteredHorizontally / UICollectionViewScrollPosition.CenteredVertically
11

これは私にとってはうまくいくようで、別の答えに似ていますが、いくつかの明確な違いがあります:

- (void)viewDidLayoutSubviews
{     
   [self.collectionView layoutIfNeeded];
   NSArray *visibleItems = [self.collectionView indexPathsForVisibleItems];
   NSIndexPath *currentItem = [visibleItems objectAtIndex:0];
   NSIndexPath *nextItem = [NSIndexPath indexPathForItem:someInt inSection:currentItem.section];

   [self.collectionView scrollToItemAtIndexPath:nextItem atScrollPosition:UICollectionViewScrollPositionNone animated:YES];
}
11
greenhouse

GCDを使用して、この動作を実現するために、viewDidLoadのメイン実行ループの次の反復にスクロールをディスパッチできます。コレクションビューが画面に表示される前にスクロールが実行されるため、フラッシュは発生しません。

- (void)viewDidLoad {
    dispatch_async (dispatch_get_main_queue (), ^{
        NSIndexPath *indexPath = YOUR_DESIRED_INDEXPATH;
        [self.collectionView scrollToItemAtIndexPath:indexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:NO];
    });
}
8
Tianyu Wang

collectionView: willDisplay:でそれを行うことをお勧めします。そうすれば、コレクションビューのデリゲートが何かを配信することを確認できます。ここに私の例:

func collectionView(_ collectionView: UICollectionView, willDisplay cell: UICollectionViewCell, forItemAt indexPath: IndexPath) {
    /// this is done to set the index on start to 1 to have at index 0 the last image to have a infinity loop
    if !didScrollToSecondIndex {
        self.scrollToItem(at: IndexPath(row: 1, section: 0), at: .left, animated: false)
        didScrollToSecondIndex = true
    }
}
4
Eike

ここですべての答え-ハック。 relaodDataの後にコレクションビューをスクロールするより良い方法を見つけました。
サブクラスコレクションビューレイアウトは、どのようなレイアウトを使用しても、スーパーコールが必要なオフセットを設定した後、メソッドprepareLayoutをオーバーライドします。
ex: https://stackoverflow.com/a/34192787/1400119

1
trickster77777