Ich habe darüber nachgedacht, einen Algorithmus, die Sie erlauben würden, zu wissen, wann der Benutzer an einem Abschnitt Header, um den Titel zu aktualisieren gescrollt hat, und nach einigen Experimenten habe ich herausgefunden, wie zu implementieren, die gewünschtes Verhalten.
Im Prinzip müssen Sie jedes Mal, wenn sich die Scroll-Position ändert, wissen, in welchem Bereich sich der Benutzer befindet, und den Titel aktualisieren. Sie tun dies über scrollViewDidScroll
auf der UIScrollViewDelegate
- Erinnerung an eine Sammlungsansicht ist eine Bildlaufansicht. Überstreichen Sie alle Überschriften und suchen Sie diejenige, die der aktuellen Bildlaufposition am nächsten ist, ohne einen negativen Versatz zu haben. Um dies zu tun, habe ich eine Eigenschaft verwendet, die ein Array der Position jedes Abschnittsheaders speichert. Wenn ein Header erstellt wird, speichere ich seine Position im Array am entsprechenden Index. Sobald Sie die Kopfzeile gefunden haben, die Ihrer Scroll-Position (oder der Indexposition dieser Kopfzeile) am nächsten ist, aktualisieren Sie einfach den Titel in der Navigationsleiste mit dem entsprechenden Titel.
In viewDidLoad
, füllen Sie die Array-Eigenschaft mit NSNull
für jeden Abschnitt Sie haben:
self.sectionHeaderPositions = [[NSMutableArray alloc] init];
for (int x = 0; x < self.sectionTitles.count; x++) {
[self.sectionHeaderPositions addObject:[NSNull null]];
}
In collectionView:viewForSupplementaryElementOfKind:atIndexPath:
, aktualisieren Sie das Array mit der Position der Kopfsicht erstellt:
NSNumber *position = [NSNumber numberWithFloat:headerView.frame.origin.y + headerView.frame.size.height];
[self.sectionHeaderPositions replaceObjectAtIndex:indexPath.section withObject:position];
In scrollViewDidScroll:
Führen Sie die Berechnungen aus, um zu bestimmen, welcher Titel für diese Bildlaufposition angezeigt werden soll:
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];
}
Dadurch wird der Titel in der Navigationsleiste korrekt aktualisiert, sobald der Benutzer über die Kopfzeile eines Abschnitts scrollt.Wenn sie zurück scrollen, wird sie ebenfalls korrekt aktualisiert. Außerdem wird der Titel korrekt festgelegt, wenn sie nicht über den ersten Abschnitt hinaus geblättert haben. Es ist jedoch nicht sehr gut mit der Rotation. Es wird auch nicht gut funktionieren, wenn Sie dynamischen Inhalt haben, der dazu führen kann, dass die gespeicherten Positionen der Header-Ansichten falsch sind. Und wenn Sie das Springen zu einem bestimmten Abschnitt unterstützen, springt der Benutzer zu einem Abschnitt, dessen Abschnittsheader des vorherigen Abschnitts noch nicht erstellt wurde, und dieser Abschnitt ist nicht groß genug, sodass sich der Abschnittskopf unterhalb der Navigationsleiste befindet (der letzte Abschnitt) vielleicht), wird der falsche Titel in der Navigationsleiste angezeigt.
Wenn jemand dies verbessern kann, um es effizienter oder sonst besser zu machen bitte tun und ich werde die Antwort entsprechend aktualisieren.
Haben Sie eine Lösung gefunden, um das gewünschte Verhalten zu erzielen? – Joey
Hallo @Joey überprüfe meine Antwort. – KDeogharkar