Je réfléchis à un algorithme qui vous permettra de savoir quand l'utilisateur a fait défiler devant une tête de section afin de mettre à jour le titre, après quelques essais, je l'ai compris comment mettre en œuvre la comportement désiré. Essentiellement, chaque fois que la position de défilement change, vous devez savoir sur quelle section se trouve l'utilisateur et mettre à jour le titre. Vous le faites via scrollViewDidScroll
sur le UIScrollViewDelegate
- en rappelant une vue de collection est une vue de défilement. Boucle sur tous les en-têtes et trouve celui qui est le plus proche de la position de défilement actuelle, sans avoir un décalage négatif. Pour ce faire, j'ai utilisé une propriété qui stocke un tableau de la position de chaque en-tête de section. Quand un en-tête est créé, je stocke sa position dans le tableau à l'index approprié. Une fois que vous avez trouvé l'en-tête le plus proche de votre position de défilement (ou l'emplacement d'index de cet en-tête), mettez simplement à jour le titre dans la barre de navigation avec le titre approprié.
En viewDidLoad
, remplissez la propriété de tableau avec NSNull
pour chaque section, vous avez:
self.sectionHeaderPositions = [[NSMutableArray alloc] init];
for (int x = 0; x < self.sectionTitles.count; x++) {
[self.sectionHeaderPositions addObject:[NSNull null]];
}
En collectionView:viewForSupplementaryElementOfKind:atIndexPath:
, mettre à jour le tableau avec la position de la vue d'en-tête créé:
NSNumber *position = [NSNumber numberWithFloat:headerView.frame.origin.y + headerView.frame.size.height];
[self.sectionHeaderPositions replaceObjectAtIndex:indexPath.section withObject:position];
En scrollViewDidScroll:
, effectuez les calculs pour déterminer quel titre est approprié à afficher pour cette position de défilement:
CGFloat currentScrollPosition = self.collectionView.contentOffset.y + self.collectionView.contentInset.top;
CGFloat smallestPositiveHeaderDifference = CGFLOAT_MAX;
int indexOfClosestHeader = NSNotFound;
//find the closest header to current scroll position (excluding headers that haven't been reached yet)
int index = 0;
for (NSNumber *position in self.sectionHeaderPositions) {
if (![position isEqual:[NSNull null]]) {
CGFloat floatPosition = position.floatValue;
CGFloat differenceBetweenScrollPositionAndHeaderPosition = currentScrollPosition - floatPosition;
if (differenceBetweenScrollPositionAndHeaderPosition >= 0 && differenceBetweenScrollPositionAndHeaderPosition <= smallestPositiveHeaderDifference) {
smallestPositiveHeaderDifference = differenceBetweenScrollPositionAndHeaderPosition;
indexOfClosestHeader = index;
}
}
index++;
}
if (indexOfClosestHeader != NSNotFound) {
self.currentTitle.text = self.sectionTitles[indexOfClosestHeader];
} else {
self.currentTitle.text = self.sectionTitles[0];
}
Ceci mettra correctement à jour le titre dans la barre de navigation une fois que l'utilisateur aura passé l'en-tête d'une section.Si elles défilent vers le haut, elles seront mises à jour correctement. Il définit également correctement le titre lorsqu'ils n'ont pas passé la première section. Cependant, il ne gère pas très bien la rotation. Cela ne fonctionnera également pas bien si vous avez un contenu dynamique, ce qui peut entraîner l'affichage incorrect des positions stockées des vues d'en-tête. Et si vous soutenez le saut vers une section spécifique, l'utilisateur saute à une section dont l'en-tête de la section précédente n'a pas encore été créée, et cette section n'est pas assez grande pour que l'en-tête soit sous la barre de navigation (la dernière section peut-être), le titre incorrect sera affiché dans la barre de navigation.
Si quelqu'un peut améliorer cela pour le rendre plus efficace ou mieux, veuillez le faire et je mettrai à jour la réponse en conséquence.
Avez-vous trouvé une solution pour obtenir le comportement souhaité? – Joey
bonjour @Joey vérifier ma réponse. – KDeogharkar