web-dev-qa-db-fra.com

Réinitialiser le défilement sur UICollectionView

J'ai un UICollectionView horizontal qui fonctionne très bien et qui défile. Lorsque je touche un élément, je mets à jour mes données et j'appelle reloadData. Cela fonctionne et les nouvelles données sont affichées dans le UICollectionView. Le problème est que la position du défilement ne change pas et qu'il affiche toujours la dernière place. Je veux réinitialiser le défilement vers le haut (ou à gauche dans mon cas). Comment puis-je faire ceci?

47
MulletDevil

Vous pouvez utiliser cette méthode pour faire défiler jusqu'à n'importe quel élément de votre choix:

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

Tu veux setContentOffset:. Il faut un CGPoint et un argument que vous pouvez définir sur ce que vous voulez à l'aide de CGPointMake, mais si vous souhaitez revenir au tout début de la collection, vous pouvez simplement utiliser CGPointZero.

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

J'utilise cela assez souvent dans différentes parties de mon application, j'ai donc étendu UIScrollView pour qu'il puisse être utilisé sur n'importe quelle vue de défilement et sous-classe de vue de défilement:

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

Donc, chaque fois que je dois réinitialiser la position:

self.collectionView.resetScrollPositionToTop()
19
Daniel Galasko

Dans Swift:

collectionView.setContentOffset(CGPointZero, animated: true)

Si vous quittez la vue qui abrite la vue de collection, apportez une modification au 2e contrôleur de vue et avez besoin que la vue de collection soit mise à jour au retour:

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

Dans ma situation, le déroulement est génial car l'appel viewDidLoad mettra à jour le contexte CoreData, l'appel reloadData s'assurera que les mises à jour collectionView refléteront le nouveau contexte CoreData, puis le contentOffset s'assurera que la table revient en haut.

12
Dave G

CGPointZero dans mon cas a déplacé le contenu de la vue de la collection parce que vous ne comptez pas l'encart de contenu. C'est ce qui a fonctionné pour moi:

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

Désolé, je n'ai pas pu commenter au moment d'écrire ces lignes, mais j'utilisais un UINavigationController et CGPointZero lui-même ne m'a pas permis d'atteindre le sommet, j'ai donc dû utiliser ce qui suit à la place.

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

J'espère que cela aidera quelqu'un à l'avenir. À votre santé!

4
Ryan

Si vous voyez que le contrôleur contient une zone sûre, codez:

collectionView.setContentOffset(CGPointZero, animated: true)

ne fonctionne pas, vous pouvez donc utiliser l'extension universelle:

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

Pour gérer un UINavigationController et une barre de navigation transparente, j'ai dû calculer le décalage supérieur supplémentaire pour correspondre parfaitement à la position du premier élément.

Code Swift 1.1:

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

À votre santé!

2
Kevin Delord
  • SOLUTION Swift 4.2 - Disons que j'ai une tableView avec chaque tableViewCell contenant une HorizontalCollectionView En raison de la réutilisation des cellules, même si la première tableViewCell défile jusqu'à la page 4, vers le bas, une autre cellule est également définie à la page 4.

Cela fonctionne dans de tels cas - Dans la fonction cellForRowAt de tableView, laissez cell = // déclarer une cellule en utilisant deque cell.myCollectionView.contentOffset = CGPoint (x: 0, y: 0)

0
Sak