Ich habe versucht, dieses Verhalten in einer Situation zu emulieren, in der ich einen benutzerdefinierten Header für eine UITableView benötigte. Ich habe meine eigene "Navigations" -Leiste gerollt, da sich diese unter einer Reihe anderer Elemente auf der Seite befindet und ich wollte, dass die Abschnittsüberschriften dem Standardverhalten "Andocken" folgen. Ich denke, ich habe eine ziemlich clevere und prägnante Möglichkeit gefunden, ein UITableView / UIScrollView zusammen mit einem anderen Objekt in einem ähnlichen Stil wie Facebook / Instagram / Chrome / etc anzupassen. Apps.
In meiner .xib-Datei habe ich meine Komponenten in eine Freiformansicht geladen: http://imgur.com/0z9yebJ (Entschuldigung, ich habe nicht den Repräsentanten, um Bilder zu inline)
Beachten Sie, dass die Tabelle in der linken Seitenleiste hinter der Hauptkopfansicht angeordnet ist. Sie können es dem Screenshot nicht entnehmen, aber es hat auch die gleiche y-Position wie die Hauptkopfansicht. Da die Eigenschaft contentInset in der UITableView nicht sichtbar ist, wird sie auf 76 festgelegt (die Höhe der Hauptheaderansicht).
Damit die Hauptheaderansicht im Einklang mit UIScrollView nach oben verschoben wird, verwende ich die scrollViewDidScroll-Methoden von UIScrollViewDelegate, um einige Berechnungen durchzuführen und das contentInset von UIScrollView sowie den Frame der Hauptheaderansicht zu ändern.
- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
UIEdgeInsets insets = scrollView.contentInset;
//tableViewInsetDelta and tableViewOriginalInsetValue are NSInteger variables that I set to 0 and 76, respectively, in viewDidLoad
tableViewInsetDelta = tableViewOriginalInsetValue + scrollView.contentOffset.y;
insets.top = tableViewOriginalInsetValue - tableViewInsetDelta;
if (scrollView.contentOffset.y > -76 && scrollView.contentOffset.y < 0) {
[scrollView setContentInset:insets];
self.pathTitleContainer.frame = CGRectMake(self.pathTitleContainer.frame.origin.x, 44 - tableViewInsetDelta, self.pathTitleContainer.frame.size.width, self.pathTitleContainer.frame.size.height);
} else if (scrollView.contentOffset.y > 0) {
insets.top = 0;
[scrollView setContentInset:insets];
self.pathTitleContainer.frame = CGRectMake(self.pathTitleContainer.frame.origin.x, -32, self.pathTitleContainer.frame.size.width, self.pathTitleContainer.frame.size.height);
} else if (scrollView.contentOffset.y < -76) {
insets.top = 76;
[scrollView setContentInset:insets];
self.pathTitleContainer.frame = CGRectMake(self.pathTitleContainer.frame.origin.x, 44, self.pathTitleContainer.frame.size.width, self.pathTitleContainer.frame.size.height);
}
}
Die erste if- Anweisung erledigt den größten Teil des schweren Hebens, aber ich musste die beiden anderen einbeziehen, um Situationen zu bewältigen, in denen der Benutzer kräftig zieht und die an scrollViewDidScroll gesendeten anfänglichen contentOffset-Werte außerhalb des Bereichs des ersten if liegen Anweisung liegen.
Letztendlich funktioniert das wirklich gut für mich. Ich hasse es, meine Projekte mit einer Reihe aufgeblähter Unterklassen zu beladen. Ich kann nicht darüber sprechen, ob dies in Bezug auf die Leistung die beste Lösung ist (ich habe immer gezögert, Code in scrollViewDidScroll einzufügen, da er ständig aufgerufen wird), aber der Code-Footprint ist der kleinste, den ich je gesehen habe Lösung für dieses Problem, ohne dass eine UITableView in eine UIScrollView verschachtelt werden muss (Apple rät in der Dokumentation davon ab, und Touch-Ereignisse werden in der UITableView etwas unkonventionell). Hoffe das hilft jemandem!