UIScrollView - Snap zur Steuerung beim Abbremsen

7

Die UIScrollView enthält viele Informationen an den Programmierer, aber ich sehe keinen offensichtlichen Weg, den Ort zu steuern, an dem die Steuerung stoppt, nachdem sie von einer Scroll-Geste abgebremst hat.

Grundsätzlich möchte ich, dass der Bildlauf in bestimmten Regionen des Bildschirms erfolgt. Der Benutzer kann immer noch wie gewohnt scrollen, aber wenn er aufhört zu scrollen, sollte die Ansicht an der relevantesten Stelle einrasten, und im Falle einer Bewegung sollte die Verlangsamung auch an diesen Stellen anhalten.

Gibt es eine einfache Möglichkeit, so etwas zu tun, oder sollte ich den einzigen Weg in Betracht ziehen, diesen Effekt zu erzielen, um ein benutzerdefiniertes Scroll-Steuerelement zu schreiben?

    
Nippysaurus 17.05.2011, 22:32
quelle

4 Antworten

27

Da UITableView eine UIScrollView-Unterklasse ist, könnten Sie die UIScrollViewDelegate-Methode implementieren:

%Vor%

Und dann berechnen Sie, was der gewünschte gewünschte Inhaltsoffset am nächsten ist, und setzen Sie dies auf den Parameter inout CGPoint.

Ich habe es gerade versucht und es funktioniert gut.

Rufen Sie zuerst den ungeführten Offset wie folgt ab:

%Vor%

Finden Sie heraus, wo Sie es haben möchten, und notieren Sie sich die Höhe des Tabellenkopfes. Hier ist ein Beispiel in meinem Code, das sich mit benutzerdefinierten Zellen beschäftigt, die US-Staaten repräsentieren:

%Vor%

Die letzte Zeile oben schreibt den Wert tatsächlich zurück in den inout-Parameter, der der Bildlaufansicht mitteilt, dass dies der Y-Offset ist, an dem Sie einrasten möchten.

Wenn Sie schließlich mit einem abgerufenen Ergebnis-Controller arbeiten und wissen möchten, was gerade gerastet wurde, können Sie so etwas tun (in meinem Beispiel ist die Eigenschaft "states" der FRC für US States). . Ich verwende diese Informationen, um einen Schaltflächentitel festzulegen:

%Vor%

OFF-THEMA HINWEIS: Wie Sie wahrscheinlich geraten haben, protokollieren die "log4Debug" -Anweisungen nur. Übrigens benutze ich Lumberjack dafür, aber ich bevorzuge die Befehlssyntax aus dem alten Log4Cocoa.

    
idStar 07.01.2012 02:45
quelle
7

Nach dem scrollViewDidEndDecelerating: und scrollViewDidEndDragging:willDecelerate: (der letzte, wenn der Parameter 'decelerate' NO ist) sollten Sie den Parameter contentOffset Ihres UIScrollView auf die gewünschte Position setzen.

Sie werden auch die aktuelle Position kennen, indem Sie die contentOffset Eigenschaft Ihres scrollview überprüfen und dann die nächste gewünschte Region berechnen, die Sie haben

Obwohl Sie kein eigenes Scroll-Steuerelement erstellen müssen, müssen Sie manuell zu den gewünschten Positionen scrollen

    
Felipe Sabino 17.05.2011 22:57
quelle
7

Um hinzuzufügen, was Felipe gesagt hat, habe ich kürzlich eine Tabellenansicht erstellt, die ähnlich wie der UIPicker in Zellen einrastet. Ein cleverer Scrollview-Delegat ist definitiv der Weg, dies zu tun (und Sie können dies auch in einer uitableview tun, da es nur eine Unterklasse von uiscrollview ist).

Ich hatte dies getan, nachdem die Bildlaufansicht verlangsamt wurde (dh nach scrollViewDidEndDragging: willDelerate: wird aufgerufen), reagierte auf scrollViewDidScroll: und berechnete das diff mit dem vorherigen Bildlaufereignis.

Wenn der Unterschied weniger als etwa 2 bis 5 Pixel beträgt, suche ich nach der nächsten Zelle und warte, bis diese Zelle um ein paar Pixel überschritten wurde. Scrolle dann zurück in die andere Richtung mit setContentOffset: animated :. Das erzeugt einen kleinen Bounce-Effekt, der für die Benutzerfreundlichkeit sehr angenehm ist, da es eine gute Rückmeldung über das Fangen gibt.

Sie müssen clever sein und nichts tun, wenn der Tisch oben oder unten springt (wenn Sie den Offset mit 0 vergleichen, oder die Inhaltsgröße wird Ihnen das sagen). Es funktioniert in meinem Fall ziemlich gut, weil die Zellen klein sind (etwa 80-100px hoch), könnte es zu Problemen kommen, wenn Sie eine reguläre Bildlaufansicht mit größeren Inhaltsbereichen haben. Natürlich bremst man nicht immer an einer Zelle vorbei. In diesem Fall scrolle ich einfach zur nächsten Zelle, und die Animation sieht ruckelig aus. Stellt sich mit der richtigen Stimmung heraus, passiert es fast nie, also bin ich damit cool. Verbringen Sie ein paar Stunden, um die tatsächlichen Werte abhängig von Ihrem spezifischen Bildschirm abzustimmen, und Sie können etwas Anständiges bekommen.

Ich habe auch den naiven Ansatz versucht und setContentOffset aufgerufen: animated: auf scrollViewDidEndDecelerating: aber es erzeugt eine wirklich seltsame Animation (oder einfach nur verwirrender Sprung, wenn du nicht animierst), der umso schlechter wird, je niedriger die Verzögerungsrate ist (Du wirst von einer langsamen Bewegung zu einer viel schnelleren springen).

Also, um die Frage zu beantworten: - Nein, es gibt keinen einfachen Weg dies zu tun, es wird einige Zeit dauern, die tatsächlichen Werte des vorherigen Algorithmus zu polieren, was auf Ihrem Bildschirm vielleicht gar nicht funktioniert, - Versuchen Sie nicht, Ihre eigene Scroll-Ansicht zu erstellen, Sie werden nur Zeit verschwenden und ein schönes Stück Technikapfel, das mit LKW-Ladungen von Käfer erstellt wurde, schlecht neu erfinden. Der Scrollview-Delegat ist der Schlüssel zu Ihrem Problem.

    
kra 27.09.2011 04:27
quelle
6

Versuchen Sie etwas wie folgt:

%Vor%

Dies nutzt den Abfall der Nachkommastellen von int aus. Geht auch davon aus, dass alle Ihre Ansichten von 0,0 aufgereiht sind und nur der contentOffset, was es in verschiedenen Bereichen erscheinen lässt.

Hinweis: Schließen Sie den Delegierten an und das funktioniert einwandfrei. Sie erhalten eine modifizierte Version - meine hat nur die tatsächlichen Konstanten lol. Ich habe die Variablen umbenannt, so dass Sie es leicht lesen können

    
Stephen J 30.03.2012 00:04
quelle

Tags und Links