Sie können den von Ihnen beschriebenen Effekt erzielen, indem Sie einen dritten Bildlauf verwenden, um die Berührungsgesten tatsächlich zu verarbeiten, und den contentOffset der anderen Bildlaufansichten manuell festlegen.
Hier ist, wie dies für vertikal scrollenden Inhalt erreichen, was ich denke, was Sie beschreiben. Im Code ist outerScrollView
die Hauptscrollansicht, innerScrollView
ist die Unterscrollansicht, die von der äußeren Scrollansicht enthalten ist, und trackingScrollView
ist die dritte Scrollansicht, die nur die Berührungen behandelt - es hat keinen Inhalt.
- Erstellen Sie die drei scrollviews so dass
trackingScrollView
genau outerScrollView
abdeckt. (Ich nehme an, Sie werden dies tun, in XIB oder Storyboard so gibt es keinen Code.)
Sobald Ihr scrollviews Inhalt haben (und wenn ihre Content oder Grenzen ändern) sollten Sie die Content von trackingScrollView
gesetzt:
self.trackingScrollView.contentSize = CGSizeMake(self.trackingScrollView.bounds.size.width,
self.outerScrollView.contentSize.height + self.innerScrollView.contentSize.height - self.innerScrollView.bounds.height);
Damit ist die Inhaltshöhe die von outerScrollView
zuzüglich der scrollbaren Entfernung von innerScrollView
, so dass trackingScrollView
über die gesamte Reisedistanz beider Scrollviews scrollen kann.
Delegierter für trackingScrollView
und scrollViewDidScroll:
- (void) scrollViewDidScroll:(UIScrollView *)scrollView {
if (scrollView == self.trackingScrollView) {
CGFloat const offsetY = self.trackingScrollView.contentOffset.y;
// Calculate the maximum outer scroll offset
CGFloat const maxOuterOffsetY = self.outerScrollView.contentSize.height - self.outerScrollView.bounds.height;
// Calculate the maximum inner scroll offset
CGFloat const maxInnerOffsetY = self.innerScrollView.contentSize.height - self.innerScrollView.bounds.height;
if (offsetY < maxOuterOffsetY) {
// Scroll is within the outer scroll area or the top bounce zone
self.outerScrollView.contentOffset = CGPointMake(0, offsetY);
self.innerScrollView.contentOffset = CGPointZero;
} else if (offsetY < maxOuterOffsetY + maxInnerOffsetY) {
// Scroll is within the inner scroll area
self.outerScrollView.contentOffset = CGPointMake(0, maxOuterOffsetY);
self.innerScrollView.contentOffset = CGPointMake(0, offsetY - maxOuterOffsetY);
} else {
// Scroll is within the bottom bounce zone
self.outerScrollView.contentOffset = CGPointMake(0, offsetY - maxInnerOffsetY);
self.innerScrollView.contentOffset = CGPointMake(0, maxInnerOffsetY);
}
} else {
// Handle other scrollviews as required
}
}
implementieren effektiv teilen wir die Tracking-Scroll-Bereich in zwei Teile. Der obere Teil steuert das Scrollen innerhalb der äußeren Scrollansicht und der untere Teil steuert die innere Scrollansicht.
Unter der Annahme, dass Bounce eingeschaltet ist (was normalerweise sein sollte), müssen wir auch Scrollen außerhalb des Scroll-Bereichs behandeln. Wir möchten, dass der Bounce auf dem äußeren Scrollview angezeigt wird, sodass der Top Bounce implizit von der ersten Bedingung behandelt wird. Der Bottom Bounce muss jedoch explizit von der dritten Bedingung behandelt werden, andernfalls würden wir den Bounce auf der inneren Scrollansicht sehen.
Um klar zu sein, in dieser Lösung die beiden Inhalt scrollviews (outerScrollView
und innerScrollView
) erhalten keine Noten überhaupt; Alle Eingaben gehen an trackingScrollView
. Wenn Sie Subviews der Inhaltsscrollviews eingeben möchten, benötigen Sie eine erweiterte Lösung. Ich glaube, dass dies getan werden kann, indem trackingScrollView
hinter outerScrollView
setzen, outerScrollView
Gestenerkenner entfernen und sie mit denen von trackingScrollView
ersetzen. Ich habe diese Technik in einer alten WWDC-Sitzung auf UIScrollView gesehen, aber ich habe es selbst nicht versucht.