115 votes

UICollectionView : défilement automatique vers la cellule à IndexPath

Avant de charger la vue de la collection, l'utilisateur définit le nombre d'images dans le tableau de la vue de la collection. Toutes les cellules ne tiennent pas sur l'écran. J'ai 30 cellules et seulement 6 sur l'écran.

La question : Comment faire défiler automatiquement la cellule contenant l'image souhaitée lors du chargement de UICollectionView ?

182voto

Bogdan Weidmann Points 755

Nouveau, Réponse éditée :

Ajouter ceci dans viewDidLayoutSubviews

SWIFT

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

Normalement, .centerVertically est le cas

ObjC

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

L'ancienne réponse fonctionne pour les anciens iOS

Ajouter ceci dans viewWillAppear :

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

104voto

LenK Points 1318

J'ai découvert que le défilement dans viewWillAppear peut ne pas fonctionner de manière fiable car la vue de la collection n'a pas encore terminé sa mise en page ; vous pouvez faire défiler jusqu'au mauvais élément.

J'ai également constaté que le défilement dans viewDidAppear fera en sorte qu'un flash momentané de la vue non défilée soit visible.

Et, si vous faites défiler à chaque fois viewDidLayoutSubviews l'utilisateur ne pourra pas faire défiler les pages manuellement, car certaines mises en page de collections entraînent la mise en place de sous-vues à chaque fois que vous faites défiler les pages.

Voici ce que j'ai trouvé qui fonctionne de manière fiable :

Objectif C :

- (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];
    }
}

Swift :

 override func viewWillLayoutSubviews() {

    super.viewWillLayoutSubviews()

      if !self.initialScrollDone {

         self.initialScrollDone = true
         self.testNameCollectionView.scrollToItem(at:selectedIndexPath, at: .centeredHorizontally, animated: true)
    }

}

17voto

raistlin Points 231

Je suis tout à fait d'accord avec la réponse ci-dessus. La seule chose est que pour moi la solution a été de mettre le code dans viewDidAppear

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

Lorsque j'ai utilisé le viewWillAppear, le défilement n'a pas fonctionné.

13voto

SVMRAJESH Points 1685

Swift :

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

Swift 3

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

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

Position de défilement :

UICollectionViewScrollPosition.CenteredHorizontally / UICollectionViewScrollPosition.CenteredVertically

12voto

greenhouse Points 111

Cela semble fonctionner pour moi, c'est similaire à une autre réponse mais il y a quelques différences distinctes :

- (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];
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X