web-dev-qa-db-fra.com

UICollectionView contentOffset change avec une disposition personnalisée

J'ai un UICollectionView avec un UICollectionViewLayout personnalisé (en fait, j'utilise cette mise en page de Nice ). 

J'ai mis contentOffset = CGPointZero dans viewDidLoad. Après viewDidLoad, cependant, le décalage est de -20 et le contenu est poussé comme suit:


picture

(Il devrait être aligné avec la ligne). Je charge la disposition de vue de collection dans le constructeur d'interface. Il semble que mon problème ressemble beaucoup à celui-ci , mais les solutions ne fonctionnent pas pour moi. 

J'ai essayé de modifier collectionViewContentSize dans mon implémentation de disposition pour m'assurer qu'elle était toujours supérieure à la taille de collectionView. Bien que cela signifie que je puisse faire défiler mon contenu vers le bas (il est plus court que la hauteur de la collectionView) et masquer l'espace supplémentaire, je peux également faire défiler vers le haut pour le voir. 

Rien ne semble fonctionner!

21
Evan Cordell

La seule solution que je pouvais trouver qui avait un comportement à peine acceptable:

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    if (self.collectionView.contentOffset.y < 0) {
        self.collectionView.contentOffset = CGPointMake(self.collectionView.contentOffset.x, 0.0);
    }
}

En plus de définir la hauteur du contenu sur fmax(self.collectionView.frame.size.height + 20, [self stackedSectionHeight]) dans collectionViewContentSize

Cela supprime l'espace au-dessus de l'en-tête de la section, mais le "rebond" du haut. Une solution assez sous-optimale, mais assez acceptable.

J'accepterai une meilleure réponse si quelqu'un en a une ou si j'en trouve une, je la mettrai à jour.

14
Evan Cordell

J'ai trouvé la raison pour laquelle cela se produit. Vérifiez la réponse acceptée à partir de cette question: La barre d’état et la barre de navigation apparaissent au-dessus des limites de ma vue dans iOS 7

En effet, nous pourrions simplement définir les propriétés edgesForExtendedLayout ou automaticallyAdjustsScrollViewInsets de UIViewController dans IB (si vous utilisez Storyboard) dans in viewDidLoad et le problème sera résolu. 

N'oubliez pas que la vérification de la disponibilité de cette propriété est disponible, car cela causera un crash dans iOS6 ou une version antérieure.

if ([self respondsToSelector:@selector(setAutomaticallyAdjustsScrollViewInsets:)]) {
    self.automaticallyAdjustsScrollViewInsets = NO;
}

Cordialement!

48
alexey.hippie

J'ai commencé à trouver ce problème apparaissant sur iOS 11, où j'avais une vue à défilement dans une vue défilement. Il m'a fallu presque un jour pour le comprendre.

Essayez de définir le comportement de réglage de l'insert de contenu:

if #available(iOS 11.0, *) {
    scrollView.contentInsetAdjustmentBehavior = .never
}

Cela corrige ma collectionview en ajustant le contenu de son contenu d'une petite quantité, car le cadre collectionview se déplacerait au-delà de la zone de sécurité de la vue de défilement englobante.

2
David Rees
let oldContentSizeHeight: CGFloat = self.colName.contentSize.height
        self.colName.reloadData()
        self.colName.layoutIfNeeded()
        self.view.layoutIfNeeded()
        self.colName.contentOffset.y = self.colName.contentOffset.y + (self.colName.contentSize.height - oldContentSizeHeight)
0
Ankit Gabani

Ceci est la version 4.2 de Swift pour la réponse correcte, mais pour le rendre utilisable, vous devez ajouter le protocole UIScrollViewDelegate:

func scrollViewDidScroll(_ scrollView: UIScrollView) {
    if self.collectionView.contentOffset.y < 0 {
        self.collectionView.contentOffset = CGPoint(x: self.collectionView.contentOffset.x, y: 0.0)
    }
}