Mit Mobile Safari können Sie Seiten wechseln, indem Sie eine Art horizontale UIScrollView-Paging-Ansicht mit einem Seitensteuerelement unten eingeben.
Ich versuche, dieses bestimmte Verhalten zu replizieren, bei dem eine horizontal scrollbare UIScrollView einige Inhalte der nächsten Ansicht anzeigt.
Das von Apple bereitgestellte Beispiel: PageControl zeigt, wie eine UIScrollView für horizontales Paging verwendet wird, aber alle Ansichten nehmen die gesamte Bildschirmbreite ein.
Wie kann ich eine UIScrollView dazu bringen, Inhalte der nächsten Ansicht anzuzeigen, wie dies bei Mobile Safari der Fall ist?
ios
iphone
cocoa-touch
uiscrollview
erster Rückmelder
quelle
quelle
Antworten:
A
UIScrollView
mit aktiviertem Paging stoppt bei einem Vielfachen seiner Rahmenbreite (oder -höhe). Der erste Schritt besteht also darin, herauszufinden, wie breit Ihre Seiten sein sollen. Machen Sie das die Breite derUIScrollView
. Stellen Sie dann die Größe Ihrer Unteransicht so groß ein, wie Sie sie benötigen, und legen Sie ihre Zentren basierend auf Vielfachen derUIScrollView
Breite der Unteransicht fest .Dann, da Sie die anderen Seiten sehen möchten, stellen Sie natürlich ein
clipsToBounds
,NO
wie mhjoy angegeben hat. Der Trick besteht nun darin, einen Bildlauf durchzuführen, wenn der Benutzer das Ziehen außerhalb des Bereichs desUIScrollView
Rahmens startet . Meine Lösung (als ich dies kürzlich tun musste) war wie folgt:Erstellen Sie eine
UIView
Unterklasse (dhClipView
), die dieUIScrollView
und ihre Unteransichten enthält. Im Wesentlichen sollte es den Rahmen haben, den SieUIScrollView
unter normalen Umständen annehmen würden. Platzieren Sie dasUIScrollView
in der Mitte desClipView
. Stellen Sie sicher, dass dasClipView
's aufclipsToBounds
gesetzt ist,YES
wenn seine Breite kleiner als die der übergeordneten Ansicht ist. Auch dasClipView
braucht einen Verweis auf dieUIScrollView
.Der letzte Schritt ist das Überschreiben
- (UIView *)hitTest:withEvent:
innerhalb derClipView
.Dies erweitert im Grunde den Berührungsbereich von
UIScrollView
auf den Rahmen der Ansicht seiner Eltern, genau das, was Sie brauchen.Eine andere Möglichkeit wäre,
UIScrollView
die- (BOOL)pointInside:(CGPoint) point withEvent:(UIEvent *) event
Methode zu unterklassifizieren und zu überschreiben. Sie benötigen jedoch weiterhin eine Containeransicht, um das Abschneiden durchzuführen, und es kann schwierig sein, anhandYES
desUIScrollView
Frames des Frames zu bestimmen, wann zurückgegeben werden soll.HINWEIS: Sie sollten sich auch Juri Pakaste's hitTest: withEvent: Modifikation ansehen, wenn Sie Probleme mit der Benutzerinteraktion in der Unteransicht haben.
quelle
UIScrollView
Unterklasse zum verzögerten Laden von Ansichten (inlayoutSubviews
) und benutzte aclippingRect
, um diepointInside:withEvent:
Tests durchzuführen. Funktioniert sehr gut und es ist keine zusätzliche Containeransicht erforderlich.UIScrollView
Unterklasse wie @ohhorob aber mit einem Behälter Ansicht für Clipping und Rückkehr[super pointInside:CGPointMake(self.contentOffset.x + self.frame.size.width/2, self.contentOffset.y + self.frame.size.height/2) withEvent:event];
inpointInside:withEvent:
. Dies funktioniert sehr gut und es gibt keine Probleme mit der Benutzerinteraktion, die in der Antwort von @ JuriPakaste erwähnt werden.- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset
stoßen, ist zu beachten, dass das Hinzufügen zu UIScrollViewDelegate in iOS5 bedeutet, dass Sie diesen Palaver nicht mehr durchlaufen müssen.Die
ClipView
obige Lösung hat bei mir funktioniert, aber ich musste eine andere-[UIView hitTest:withEvent:]
Implementierung durchführen. In der Version von Ed Marty konnte die Benutzerinteraktion nicht mit vertikalen Bildlaufansichten arbeiten, die ich in der horizontalen habe.Die folgende Version hat bei mir funktioniert:
quelle
Stellen Sie die Rahmengröße von scrollView wie folgt ein:
Jetzt können Sie schwenken
self.view
und der Inhalt von scrollView wird gescrollt.Verwenden Sie
scrollView.clipsToBounds = NO;
diese Option auch , um ein Abschneiden des Inhalts zu verhindern.quelle
Ich habe mich selbst für das benutzerdefinierte UIScrollView entschieden, da es die schnellste und einfachste Methode war, die mir erschien. Ich habe jedoch keinen genauen Code gesehen, also dachte ich, ich würde ihn teilen. Ich brauchte eine UIScrollView mit kleinem Inhalt, und daher war die UIScrollView selbst klein, um den Paging-Effekt zu erzielen. Wie in der Post angegeben, können Sie nicht darüber streichen. Aber jetzt kannst du.
Erstellen Sie eine Klasse CustomScrollView und eine Unterklasse UIScrollView. Dann müssen Sie dies nur noch in die .m-Datei einfügen:
Auf diese Weise können Sie von einer Seite zur anderen (horizontal) scrollen. Passen Sie die Grenzen entsprechend an, um Ihren Wisch- / Bildlauf-Berührungsbereich festzulegen. Genießen!
quelle
Ich habe eine andere Implementierung vorgenommen, die die Bildlaufansicht automatisch zurückgeben kann. Es muss also kein IBOutlet vorhanden sein, das die Wiederverwendung im Projekt einschränkt.
quelle
Ich habe eine weitere potenziell nützliche Änderung für die ClipView hitTest-Implementierung. Ich wollte keinen UIScrollView-Verweis auf ClipView bereitstellen. Mit der folgenden Implementierung können Sie die ClipView-Klasse erneut verwenden, um den Hit-Test-Bereich von irgendetwas zu erweitern, ohne ihn mit einer Referenz versehen zu müssen.
quelle
Ich habe den oben genannten Vorschlag umgesetzt, aber das, was
UICollectionView
ich verwendet habe, hat alles außerhalb des Rahmens als außerhalb des Bildschirms liegend angesehen . Dies führte dazu, dass Zellen in der Nähe nur außerhalb der Grenzen gerendert wurden, wenn der Benutzer auf sie zu scrollte, was nicht ideal war.Am Ende habe ich das Verhalten einer Bildlaufansicht emuliert, indem ich dem Delegaten (oder
UICollectionViewLayout
) die folgende Methode hinzugefügt habe .Dies vermeidet die Delegation der Swipe-Aktion vollständig, was ebenfalls ein Bonus war. Das
UIScrollViewDelegate
hat eine ähnliche Methode,scrollViewWillEndDragging:withVelocity:targetContentOffset:
die zum Blättern von UITableViews und UIScrollViews verwendet werden kann.quelle
Aktivieren Sie das Auslösen von Tap-Ereignissen in untergeordneten Ansichten der Bildlaufansicht, während Sie die Technik dieser SO-Frage unterstützen. Verwendet einen Verweis auf die Bildlaufansicht (self.scrollView) zur besseren Lesbarkeit.
Fügen Sie dies Ihrer untergeordneten Ansicht hinzu, um das Berührungsereignis zu erfassen:
(Dies ist eine Variation der Lösung von user1856273. Aus Gründen der Lesbarkeit bereinigt und mit der Fehlerbehebung von Bartserk versehen. Ich dachte daran, die Antwort von user1856273 zu bearbeiten, aber es war eine zu große Änderung, um sie vorzunehmen.)
quelle
meine Version Drücken Sie die Taste auf der Schriftrolle - Arbeit =)
aber nur [[self subviews] objectAtIndex: 0] muss eine Schriftrolle sein
quelle
Hier ist eine schnelle Antwort, die auf Ed Martys Antwort basiert, aber auch die Modifikation von Juri Pakaste enthält, um das Tippen auf Schaltflächen usw. in der Bildlaufansicht zu ermöglichen.
quelle