Ich habe eine Bildlaufansicht, die der Breite des Bildschirms entspricht, aber nur etwa 70 Pixel hoch ist. Es enthält viele 50 x 50 Symbole (mit Leerzeichen um sie herum), aus denen der Benutzer auswählen kann. Ich möchte jedoch immer, dass sich die Bildlaufansicht seitenweise verhält und immer mit einem Symbol genau in der Mitte stoppt.
Wenn die Symbole die Breite des Bildschirms hätten, wäre dies kein Problem, da sich das Paging von UIScrollView darum kümmern würde. Aber weil meine kleinen Symbole viel kleiner als die Inhaltsgröße sind, funktioniert es nicht.
Ich habe dieses Verhalten bereits in einem App-Aufruf von AllRecipes gesehen. Ich weiß nur nicht, wie ich es machen soll.
Wie kann ich Paging pro Symbolgröße zum Laufen bringen?
quelle
Es gibt auch eine andere Lösung, die wahrscheinlich ein bisschen besser ist, als die Bildlaufansicht mit einer anderen Ansicht zu überlagern und hitTest zu überschreiben.
Sie können UIScrollView in Unterklassen unterteilen und dessen pointInside überschreiben. Die Bildlaufansicht kann dann auf Berührungen außerhalb des Rahmens reagieren. Natürlich ist der Rest der gleiche.
quelle
return [self.superview pointInside:[self convertPoint:point toView:self.superview] withEvent:event];
@amrox @Split Sie benötigen keine responseInsets, wenn Sie eine Übersicht haben, die als Clipansicht fungiert.Ich sehe viele Lösungen, aber sie sind sehr komplex. Eine viel einfachere Möglichkeit , kleine Seiten zu haben, aber dennoch alle Bereiche scrollbar zu halten, besteht darin, den Bildlauf zu verkleinern und in die
scrollView.panGestureRecognizer
übergeordnete Ansicht zu verschieben. Dies sind die Schritte:Reduzieren Sie die Größe Ihrer scrollView
Stellen Sie sicher, dass Ihre Bildlaufansicht paginiert ist und keine Unteransicht ausschneidet
Verschieben Sie im Code die Scrollansicht-Schwenkgeste in die übergeordnete Containeransicht mit voller Breite:
quelle
Die akzeptierte Antwort ist sehr gut, aber sie funktioniert nur für die
UIScrollView
Klasse und keinen ihrer Nachkommen. Zum Beispiel , wenn Sie viele Ansichten und Konvertit einer habenUICollectionView
, werden Sie nicht in der Lage sein , diese Methode zu verwenden, da die Sammlung Ansicht wird entfernen Ansichten , dass es denkt , ist „nicht sichtbar“ (also auch wenn sie nicht beschnitten sind, werden sie verschwinden).Der Kommentar zu diesen Erwähnungen
scrollViewWillEndDragging:withVelocity:targetContentOffset:
ist meiner Meinung nach die richtige Antwort.Sie können innerhalb dieser Delegatmethode die aktuelle Seite / den aktuellen Index berechnen. Dann entscheiden Sie, ob die Geschwindigkeit und der Zielversatz eine Bewegung "Nächste Seite" verdienen. Sie können dem
pagingEnabled
Verhalten ziemlich nahe kommen .Hinweis: Ich bin heutzutage normalerweise ein RubyMotion-Entwickler. Bitte prüfen Sie diesen Obj-C-Code auf Richtigkeit. Entschuldigung für die Mischung aus camelCase und snake_case, ich habe einen Großteil dieses Codes kopiert und eingefügt.
quelle
convertXToIndex:
undconvertIndexToX:
angeben?velocity
Null heben , springt sie zurück, was seltsam ist. Also habe ich eine bessere Antwort.kPageWidth ist die Breite, die Ihre Seite haben soll. kPageOffset ist, wenn Sie nicht möchten, dass die Zellen linksbündig ausgerichtet sind (dh wenn Sie möchten, dass sie mittig ausgerichtet sind, setzen Sie dies auf die halbe Breite Ihrer Zelle). Andernfalls sollte es Null sein.
Dies ermöglicht auch nur das Scrollen einer Seite gleichzeitig.
quelle
Schauen Sie sich die
-scrollView:didEndDragging:willDecelerate:
Methode anUIScrollViewDelegate
. Etwas wie:Es ist nicht perfekt - als ich diesen Code das letzte Mal ausprobiert habe, hatte ich ein hässliches Verhalten (Springen, wie ich mich erinnere), als ich von einer Rolle mit Gummibändern zurückkam. Sie können dies möglicherweise vermeiden, indem Sie einfach die
bounces
Eigenschaft der Bildlaufansicht auf setzenNO
.quelle
Da ich noch keinen Kommentar abgeben darf, werde ich hier meine Kommentare zu Noahs Antwort hinzufügen.
Ich habe dies erfolgreich mit der von Noah Witherspoon beschriebenen Methode erreicht. Ich habe das Sprungverhalten
setContentOffset:
umgangen, indem ich die Methode einfach nicht aufgerufen habe, wenn die Bildlaufansicht hinter ihren Rändern liegt.Ich fand auch, dass ich die
-scrollViewWillBeginDecelerating:
Methode implementieren mussteUIScrollViewDelegate
, um alle Fälle zu erfassen.quelle
Ich habe die obige Lösung ausprobiert, die eine transparente Ansicht mit pointInside: withEvent: overrided überlagert. Das hat bei mir ziemlich gut funktioniert, ist aber in bestimmten Fällen zusammengebrochen - siehe meinen Kommentar. Am Ende habe ich das Paging selbst mit einer Kombination aus scrollViewDidScroll implementiert, um den aktuellen Seitenindex und scrollViewWillEndDragging: withVelocity: targetContentOffset und scrollViewDidEndDragging: willDecelerate zu verfolgen, um an der entsprechenden Seite zu fangen. Beachten Sie, dass die Will-End-Methode nur für iOS5 + verfügbar ist. Sie eignet sich jedoch sehr gut zum Zielen auf einen bestimmten Versatz, wenn die Geschwindigkeit! = 0. Insbesondere können Sie dem Anrufer mitteilen, wo die Bildlaufansicht mit Animation landen soll, wenn Geschwindigkeit in a vorhanden ist bestimmte Richtung.
quelle
Stellen Sie beim Erstellen der Bildlaufansicht Folgendes sicher:
Fügen Sie dann Ihre Unteransichten mit einem Versatz zum Index * hinzu, der der Indexhöhe * des Scrollers entspricht. Dies ist für einen vertikalen Scroller:
Wenn Sie es jetzt ausführen, sind die Ansichten voneinander getrennt, und bei aktiviertem Paging werden sie einzeln gescrollt.
Fügen Sie dies also in Ihre viewDidScroll-Methode ein:
Die Frames der Unteransichten sind immer noch voneinander entfernt. Wir verschieben sie nur über eine Transformation, während der Benutzer einen Bildlauf durchführt.
Sie haben auch Zugriff auf die Variable p oben, die Sie für andere Zwecke wie Alpha oder Transformationen in den Unteransichten verwenden können. Wenn p == 1 ist, wird diese Seite vollständig angezeigt oder tendiert eher zu 1.
quelle
Versuchen Sie, die contentInset-Eigenschaft von scrollView zu verwenden:
Es kann einige Zeit dauern, bis Sie mit Ihren Werten herumgespielt haben, um das gewünschte Paging zu erzielen.
Ich habe festgestellt, dass dies im Vergleich zu den veröffentlichten Alternativen sauberer funktioniert. Das Problem bei der Verwendung der
scrollViewWillEndDragging:
Delegate-Methode ist, dass die Beschleunigung für langsame Bewegungen nicht natürlich ist.quelle
Dies ist die einzige wirkliche Lösung für das Problem.
quelle
Hier ist meine Antwort. In meinem Beispiel hat a,
collectionView
das einen Abschnittskopf hat, die scrollView, die wir erstellen möchten, einen benutzerdefiniertenisPagingEnabled
Effekt, und die Höhe der Zelle ist ein konstanter Wert.quelle
Verfeinerte Swift-Version der
UICollectionView
Lösung:quelle
Alter Thread, aber erwähnenswert meine Einstellung dazu:
Auf diese Weise können Sie a) die gesamte Breite der Bildlaufansicht zum Schwenken / Wischen verwenden und b) mit den Elementen interagieren, die außerhalb der ursprünglichen Grenzen der Bildlaufansicht liegen
quelle
Für das UICollectionView-Problem (das für mich eine UITableViewCell einer Sammlung horizontal scrollender Karten mit "Tickern" der kommenden / vorherigen Karte war) musste ich einfach auf die Verwendung von Apples nativem Paging verzichten. Damiens Github-Lösung hat bei mir hervorragend funktioniert. Sie können die Ticklergröße anpassen, indem Sie die Kopfzeilenbreite erhöhen und sie beim ersten Index dynamisch auf Null setzen, damit Sie keinen großen leeren Rand erhalten
quelle