6

J'implémente un calendrier à défilement infini. Mon problème est que je voudrais définir le mois en cours comme le titre dans la barre de navigation et il devrait mettre à jour tout en faisant défiler - une fois que vous passez la vue d'en-tête de section le titre devrait mettre à jour dans la barre de navigation.Comment détecter le défilement d'une nouvelle section dans un UICollectionView?

Une solution possible serait de définir le titre de vue dans la méthode appelée - (UICollectionReusableView *)collectionView:(UICollectionView *)collectionView viewForSupplementaryElementOfKind:(NSString *)kind atIndexPath:(NSIndexPath *)indexPath de sorte que, lorsque je calcule un nouvel en-tête de section, il mette également à jour le titre. Le problème avec ceci est que le titre change quand la nouvelle section est au bas de la page.

Currently displaying the Section Header as title, not optimal

Est-il possible de connaître la « section courante » de UICollectionView fois que l'utilisateur a fait défiler à elle? Ou pouvez-vous penser à un moyen d'améliorer ma solution actuelle?

Pour aider les lecteurs de ce post, j'ai posté mon propre exemple de code pour cette question à cette GitHub repo.

+0

Avez-vous trouvé une solution pour obtenir le comportement souhaité? – Joey

+0

bonjour @Joey vérifier ma réponse. – KDeogharkar

Répondre

0

changement ligne ci-dessous dans la méthode viewForSupplementaryElementOfKind:

self.title = [df stringFromDate:[self dateForFirstDayInSection:indexPath.section]]; 

à ceci:

if(![[self dateForFirstDayInSection:indexPath.section-1] isKindOfClass:[NSNull class]]){ 
     self.title = [df stringFromDate:[self dateForFirstDayInSection:indexPath.section-1]]; 
} 

espère que cela vous aidera.

+0

Oui, cela a résolu le problème spécifique. Merci! – maggix

+0

Cela ne fonctionnera pas lorsque l'en-tête suivant n'est pas visible à l'écran, et lorsque vous faites défiler vers le haut, il change le titre avant que la section précédente ne soit visible. – Joey

0

Oui, le problème est que le pied de page et l'en-tête ne sont pas présents dans la collection visibleCells. Il existe un autre moyen de détecter le défilement de l'en-tête/du pied de section. Ajoutez juste un contrôle là et trouvez le rect pour cela. Comme ceci:

func scrollViewDidScroll(scrollView: UIScrollView) { 

    if(footerButton.tag == 301) 
    { 
     let frame : CGRect = footerButton.convertRect(footerButton.frame, fromView: self.view) 
     //some process for frame 
    } 


} 
2

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.

+0

Salut Joey, merci pour la réponse élaborée! – maggix

Questions connexes