Ich habe zwei Tage damit verbracht, die verschiedenen Lösungen für auszuprobieren gemischte und reine Autolayout-Ansätze auszuprobieren , um ein triviales Scrollview-Setup vor dem Autolayout zu erreichen, und es ist jetzt offiziell - ich muss zu dumm sein. Ich richte dies hauptsächlich im Storyboard ein (nun, es ist einfach so wie es ist).
Hier ist meine Bitte um Hilfe.
Ansichtsbaum:
UIView
-UIView
-UIView
..-UIScrollview
...-UIButton
...-UIButton
...-UIButton
Die Tasten sollen horizontal scrollen (von links nach rechts und umgekehrt). Kann jemand bitte mitteilen, wie die Einschränkungen festgelegt werden sollen, um dies mit reinem Autolayout zu erreichen?
- -
Ich habe den gemischten Ansatz so ausprobiert:
UIView
- UIView
- UIView
..-UIScrollview
...-UIView (contentview)
....-UIButton
....-UIButton
....-UIButton
... und Festlegen von Einschränkungen für Breite und Höhe für die contentview
und dietranslatesAutoresizingMaskIntoConstraints
Einstellungen gemäß Apples TechNote. Die Schaltflächen und die Bildlaufansicht werden mithilfe von Einschränkungen eingerichtet. Dadurch wird die Bildlaufansicht gescrollt (yay), aber leider wird zu weit gescrollt! Soweit ich das beurteilen kann, hat sich die Bildlaufbreite gegenüber dem, auf den ich die Inhaltsansicht eingestellt habe, irgendwie verdoppelt ??? !!! ???
Ich habe auch den reinen Autolayout-Ansatz ausprobiert, sowohl mit contentview
als auch ohne. Alle Ansichten sind translatesAutoresizingMaskIntoConstraints=NO
, außer self.view
. Die Schaltflächen haben feste Breiten- / Höhenbeschränkungen und sind an allen vier Kanten der Bildlaufansicht befestigt. Nichts rollt.
Ich bin total verblüfft, warum ich es nicht richtig zum Laufen bringen kann. Jede Hilfe wird sehr geschätzt, und wenn Sie weitere Informationen benötigen, fragen Sie bitte!
AKTUALISIERTER Screenshot mit Lösung - buttonZ Einschränkungen:
EDIT @ Jamie Forrest Die Lösung stellt sich also als die falsche nachfolgende Einschränkung für die letzte Schaltfläche heraus. Anstelle von 6441 war der Wert, den ich eingestellt hatte, negativ, -6441. Das Schwierige ist, dass beim Festlegen des Werts im Storyboard zwei Optionen in der Pin-Symbolleiste angezeigt werden:
Der aktuelle Canvas-Wert ist negativ (führt zu keinem Bildlauf), und die folgende Option ist positiv (Bildlauf aktivieren). Das heißt, ich bin nicht dumm, aber zumindest halb blind, denke ich. Obwohl es zu meiner Verteidigung nicht etwas störend ist, dass XCode keinen Fehler für die "falsche" Einstellung anzeigt?
WIEDER BEARBEITET Nun, das ist lustig ... Ändern des nachgestellten Werts von -6441 (kein Bildlauf) auf 6441 aktiviertes Bildlauf. Aber mein alter Freund, die "zu große Inhaltsgröße", war zurück, was zu einer Inhaltsgröße führte, die doppelt so groß war, wie sie sein sollte! Die Lösung, um den richtigen Bildlauf für den Inhalt zu erhalten, bestand darin, die nachfolgende Einschränkung auf NULL zu setzen! Dies ist nicht offensichtlich, wenn Sie in Storyboard arbeiten, aber wenn Sie sich den Code von @Infinity James ansehen, ist es genau das, was es sein sollte.
quelle
contentSize
einesUIScrollView
nur mit Auto - Layout. Und es ist dascontentSize
, was definiert, wie viel Sie scrollen können. Sie müssen dies also irgendwann irgendwo manuell einstellen. Im Übrigen können Sie Layoutbeschränkungen verwenden, um Ansichtsrahmen relativ zueinander einzurichten.Antworten:
Es ist schwierig, die genauen Werte und Einstellungen Ihrer Einschränkungen zu erkennen, wenn Sie sie hier eingefügt haben. Daher bin ich mir nicht sicher, ob Sie sich Ihre Screenshots ansehen, in denen Sie einen Fehler gemacht haben.
Anstelle einer Erklärung, was in Ihrem Setup nicht stimmt, habe ich ein grundlegendes Beispielprojekt mit einer sehr ähnlichen Ansichtshierarchie und Einschränkungskonfiguration wie die von Ihnen beschriebene erstellt. Das horizontale Scrollen funktioniert wie erwartet im Beispielprojekt, das den von Apple im Technischen Hinweis beschriebenen Ansatz "Pure AutoLayout" verwendet .
Ich hatte auch große Probleme damit, Auto Layout zum Laufen zu bringen
UIScrollView
. Der Schlüssel, damit es funktioniert, besteht darin, sicherzustellen, dass alle Elemente in der Bildlaufansicht zusammengenommen Einschränkungen aufweisen, die schließlich mit allen Seiten der Bildlaufansicht verknüpft sind und dazu beitragen, dass das AutoLayout-System eine Inhaltsgröße für das Bild bestimmen kann Bildlaufansicht, die größer als der Rahmen ist. Es sieht so aus, als hätten Sie versucht, dies in Ihrem Code zu tun, aber vielleicht hatten Sie einige überflüssige Einschränkungen, die die contentSize zu klein machten.Wie bereits erwähnt, können Sie mit AutoLayout und UIScrollview die contentSize nicht mehr explizit festlegen. Das AutoLayout-System berechnet die contentSize basierend auf Ihren Einschränkungen.
Ich fand dieses E-Book-Kapitel auch sehr hilfreich, um zu verstehen, wie das alles funktioniert. Hoffe das alles hilft.
quelle
LOL Willkommen im Dummheitsclub. Ich bin einer der Gründer. : D.
Für das VERTIKALE Scrollen : Die einzige Möglichkeit, es zum Laufen zu bringen (iOS 8, Xcode 6 und reines Autolayout), bestand darin, meiner Bildlaufansicht die folgenden Einschränkungen hinzuzufügen (alle in Bezug auf die Übersicht):
Meine Struktur:
Dies ist das Endergebnis:
Dies ist das Setup:
Ganzer Bildschirm
Hoffentlich würde dies jemanden davor bewahren, um 5 Uhr morgens zu schlafen. : D.
quelle
Einfaches Beispiel in sich geschlossen
Gemessen an der hohen Anzahl von Stimmen zu der Frage und der niedrigen Anzahl von Stimmen zu den Antworten finden die Menschen hier keine verständliche und schnelle Lösung. Lassen Sie mich versuchen, eine hinzuzufügen. Dieses Projekt ist ein in sich geschlossenes Beispiel, das vollständig im Interface Builder erstellt wurde. Sie sollten in der Lage sein, es in 10 Minuten oder weniger durchzuarbeiten. Anschließend können Sie die erlernten Konzepte auf Ihr eigenes Projekt anwenden.
In der ursprünglichen Frage wird nach Bildlaufschaltflächen gefragt. Hier benutze ich nur
UIView
s, aber sie können jede Ansicht darstellen, die Sie mögen. Ich habe mich auch für das horizontale Scrollen entschieden, da die Storyboard-Screenshots für dieses Format kompakter sind. Die Prinzipien für das vertikale Scrollen sind jedoch dieselben.Schlüssel Konzepte
UIScrollView
sollte nur eine Unteransicht verwenden. Dies ist eine 'UIView', die als Inhaltsansicht dient und alles enthält, was Sie scrollen möchten.Starten Sie ein neues Projekt
Es kann sich nur um eine Einzelansicht handeln.
Storyboard
In diesem Beispiel erstellen wir eine horizontale Bildlaufansicht. Wählen Sie den View Controller und dann im Größeninspektor Freiform aus. Machen Sie die Breite
1,000
und die Höhe300
. Dies gibt uns nur Platz im Storyboard, um Inhalte hinzuzufügen, die gescrollt werden.Fügen Sie eine Bildlaufansicht hinzu
Fügen Sie ein hinzu
UIScrollView
und stecken Sie alle vier Seiten in die Stammansicht des Ansichtscontrollers.Fügen Sie eine Inhaltsansicht hinzu
Fügen Sie der
UIView
Bildlaufansicht eine als Unteransicht hinzu. Das ist der Schlüssel. Versuchen Sie nicht, der Bildlaufansicht viele Unteransichten hinzuzufügen. Fügen Sie einfach eine einzelne hinzuUIView
. Dies ist Ihre Inhaltsansicht für die anderen Ansichten, die Sie scrollen möchten. Befestigen Sie die Inhaltsansicht an allen vier Seiten an der Bildlaufansicht.Gleiche Höhen
CommandKlicken Sie nun in der Dokumentübersicht sowohl auf die Inhaltsansicht als auch auf die übergeordnete Ansicht der Bildlaufansicht, um beide auszuwählen. Stellen Sie dann die Höhen gleich ein ( Controlziehen Sie von der Inhaltsansicht in die Bildlaufansicht). Dies ist auch der Schlüssel. Da wir horizontal scrollen, weiß die Inhaltsansicht der Bildlaufansicht nicht, wie hoch sie sein soll, es sei denn, wir stellen sie auf diese Weise ein.
Hinweis:
Inhalt hinzufügen
Addiere drei
UIView
s und gib ihnen alle Einschränkungen. Ich habe für alles 8-Punkte-Ränder verwendet.Einschränkungen:
Das Festlegen der Breitenbeschränkungen ist ebenfalls wichtig, damit die Bildlaufansicht weiß, wie breit die Inhaltsansicht sein wird.
Fertig
Das ist alles. Sie können Ihr Projekt jetzt ausführen. Es sollte sich wie das Bildlaufbild oben in dieser Antwort verhalten.
Tauschen Sie für vertikales Scrollen einfach alle Breiten- und Höhenrichtungen in diesem Beispiel aus (getestet und funktionsfähig).
Weitere Studie
quelle
Die contentSize wird implizit festgelegt, indem die Einschränkungen in UIScrollView angewendet werden.
Wenn Sie beispielsweise eine UIScrollView in einer UIView haben, sieht diese folgendermaßen aus (wie Sie sicher wissen):
Dadurch wird die scrollView so eingestellt, dass sie die Größe der containerView ausfüllt (daher muss die containerView eine bestimmte Größe haben).
Sie können dann die Inhaltsgröße von UIScrollView anpassen, indem Sie implizit festlegen, dass sie groß genug ist, um die Schaltflächen wie folgt zu halten:
quelle
Es gibt so viele Fragen zur Verwendung von AutoLayout mit UIScrollView. Der wichtigste Punkt, den wir ignorieren, ist, dass die inneren Ansichten von UIScrollView Einschränkungen für die Inhaltsansicht , nicht jedoch für die UIScrollView selbst darstellen. Weitere Informationen finden Sie im Technischen Hinweis TN2154 :
Die folgende Abbildung zeigt Folgendes:
Sie können feststellen, dass der nachfolgende Speicherplatz 500 Punkte beträgt. Wenn die Einschränkung für UIScrollView vorgenommen wird, wird die Ansicht falsch platziert und sollte ihren Rahmen aktualisieren. Keine Warnungen und keine Fehler. Weil alle Einschränkungen gegen die Inhaltsansicht gerichtet sind.
UIScrollView berechnet die Größe der Inhaltsansicht gemäß den Einschränkungen der inneren Ansichten. (Für das Beispiel ist die Inhaltsgröße: Breite = 100 (vorderer Bereich) + 200 (Breite der Ansicht) + 500 (nachfolgender Bereich), Höhe = 131 (oberer Abstand) + 200 (Höhe) + 269 (unterer Abstand)
So fügen Sie Einschränkungen für Ansichten in UIScrollView hinzu:
Und alles ist erledigt.
Eine einfache Möglichkeit, mit AutoLayout mit Bildlaufansicht umzugehen, besteht darin, eine Containeransicht hinzuzufügen, die alle Unteransichten in der Bildlaufansicht enthält.
Schlussfolgerung: Der wichtigste Punkt zum Verständnis von AutoLayout mit UIScrollView sind innere Ansichten, die Einschränkungen für die Inhaltsansicht, nicht jedoch für UIScrollView selbst festlegen.
angehängter Beispielcode
quelle
Die folgende Lösung funktionierte für mich für scrollView mit Autolayout und ohne contentSize :
Und du bist fertig. Jetzt können Sie dieser Ansicht eine beliebige Anzahl von Steuerelementen hinzufügen und die für einander relevanten Einschränkungen anwenden (die ohne diese Ansicht nicht funktionieren). Wenn Sie diese Ansicht nicht verwenden möchten, müssen Sie Einschränkungen für jedes Steuerelement anwenden, das sich auf scrollView bezieht (nicht aufeinander bezogen).
Der überwältigende Tipp ..............
Kritisch . Nehmen wir zur Klarheit an, die UIScrollView ist 1000 breit und 100 hoch. (Normalerweise sind diese Werte natürlich dynamisch, abhängig von der Breite des Geräts usw. Aber sagen Sie vorerst nur 1000 breit und 100 hoch.) Nehmen wir an, Sie führen einen horizontalen Bildlauf durch. Fügen Sie also eine UIView in die UIScrollView ein. (Dies ist die "Inhaltsansicht".) Legen Sie alle vier Einschränkungen der Inhaltsansicht oben, unten, nach oben und nach hinten in der Bildlaufansicht fest. Machen Sie sie alle auf Null, auch wenn das falsch erscheint. Stellen Sie die Höhe des Inhalts-UIView auf 100 ein und vergessen Sie das. Jetzt: Sie möchten horizontal scrollen, stellen Sie also die Breite der Inhaltsansicht auf 1225 ein.
Beachten Sie, dass die Breite der Inhaltsansicht jetzt 225 größer ist als die Breite der übergeordneten Bildlaufansicht. Das ist in Ordnung: Tatsächlich MÜSSEN Sie das tun. Beachten Sie, dass
... Sie setzen die nachlaufende Breite NICHT auf negativ 225 ...
Sie würden denken, Sie müssten die Breiten wie gewohnt "anpassen" . Aber wenn Sie das tun, wird es überhaupt nicht funktionieren.
Sie müssen die führenden und nachfolgenden Zahlen auf NULL setzen , niemals negativ (obwohl die Breite "größer" ist).
Interessanterweise können Sie die führenden / nachfolgenden Zahlen auf einen beliebigen positiven Wert setzen (versuchen Sie, "50" zu sagen), und Sie erhalten eine Art Absprungspielraum. (Es sieht oft gut aus: probieren Sie es aus.) Jeder negative Wert an beiden Enden wird "lautlos brechen".
Beachten Sie, dass ärgerlicherweise oft Xcode (ab 7.3.1 sowieso),
wird 'hilfreich' diese Werte für Sie auf negative Zahlen setzen!
weil es versucht, sie automatisch für Sie zu zählen. Wenn ja, wird es lautlos brechen. Setzen Sie zunächst alle vier Werte auf Null. Stellen Sie die Breite der Inhaltsansicht viel breiter als die "1000" im Beispiel ein.
Bearbeitet: Ich habe für den größten Teil meiner Anforderungen UITableView anstelle von UIScrollView verwendet. Als tableView erscheint mir viel flexibler und dynamischer.
quelle
Ich gehe davon aus, dass Sie auf Probleme mit dem stoßen
contentSize
. In diesem BlogbeitragcontentSize
erfahren Sie, wie Sie mit einem "reinen" AutoLayout-Ansatz umgehen. Der Kern davon ist, dass Ihre Einschränkungen implizit die Inhaltsgröße definieren. Sie legen es NIEMALS explizit fest, wenn Sie AutoLayout verwenden. Ich habe am Ende des Blogposts ein Beispielprojekt angehängt, um zu demonstrieren, wie es funktioniertquelle
In den technischen Notizen befindet sich ein Teil, den Sie möglicherweise durchgesehen haben. Sie können die Inhaltsgröße einer Bildlaufansicht implizit mithilfe von Einschränkungen festlegen, die an den Rändern der Bildlaufansicht festgelegt sind.
Hier ist ein einfaches Beispiel. Erstellen Sie ein Storyboard mit einer Ansicht und einer Bildlaufansicht. Stellen Sie die Einschränkungen für Bildlaufansichten so ein, dass sie der Größe der Ansicht entsprechen, in die Sie sie eingefügt haben.
Fügen Sie in dieser Bildlaufansicht eine einzelne Ansicht hinzu. Legen Sie die Größe dieser Ansicht mithilfe von Einschränkungen explizit fest (und stellen Sie sicher, dass die Größe größer als die Bildlaufansicht ist).
Fügen Sie dieser inneren Ansicht nun vier weitere Einschränkungen hinzu, und sperren Sie die vier Kanten der inneren Ansicht mit der übergeordneten Bildlaufansicht. Diese vier Einschränkungen bewirken, dass die Inhaltsgröße erweitert wird, um die innere Ansicht zu berücksichtigen.
Wenn Sie mehrere Ansichten zu einer Bildlaufansicht hinzufügen möchten, z. B. horizontal angeordnet, sperren Sie die linke Seite der ersten Unteransicht links von der Bildlaufansicht, sperren die Unteransichten horizontal und rechts Seite der letzten Unteransicht zur rechten Seite der Bildlaufansicht. Diese Einschränkungen würden dazu führen, dass die Inhaltsgröße der Bildlaufansicht erweitert wird, um alle Unteransichten und ihre Einschränkungen zu berücksichtigen.
quelle
Wenn Ihre Frage lautet: "Wie füge ich eine Reihe von UITextFields in eine vertikal scrollende UIScrollView ein, sodass sie sich bei Fokus aus der Tastatur entfernen", lautet die beste Antwort:
Tu es nicht.
Verwenden Sie stattdessen einen UITableViewController mit statischen Zellen.
Sie erhalten dieses Scroll-out-of-the-Way-Verhalten kostenlos und alle Inhaltseinfügungen funktionieren nur, wenn Ihr View Controller in einem UINavigationController angezeigt wird.
quelle
Sie sollten Ihr Layout so organisieren , dass es 2
ViewControllerView
enthältScrollView
,ScrollView
enthältContainerView
,ContainerView
enthältLabels
Befolgen Sie dann 3 Schritte, um Ihre
ScrollView
Dose zu scrollenScrollView
(oben / rechts / unten / links) aufViewControllerView
ContainerView
(oben / rechts / unten / links) aufScrollView
Horizontally in Container
( nicht setzenVertically in Container
)Label1
Stift ( oben / rechts / links) anContainerView
Label1
Stift (rechts / links / unten ) anContainerView
und oben anLabel1
Ich hoffe das hilft
quelle
Der reine Autolayout-Ansatz funktioniert hervorragend, aber es ist ziemlich mühsam, sich einzurichten, wenn Sie von einem Nicht-Autolayout migrieren. Ich habe es jetzt ein paar Mal gemacht und ich habe ein paar allgemeine Tipps:
quelle
Nachdem ich mich einige Zeit mit diesem Problem befasst hatte, fand ich endlich eine Lösung. Ich arbeite mit Storyboards mit universellen Klassengrößen (600 x 600). Ich habe eine UIView (contentView) in der Größe der scrollView erstellt und Einschränkungen für Top, Bottom, Leading und Trailing to scrollRiew erstellt. Dann habe ich die Größe der contentView manuell auf 600x600 gekürzt. Das Storyboard versuchte nicht mehr, die Größe zu ändern, und ich konnte arbeiten, aber die Ansicht auf dem realen Gerät oder Simulator sah schrecklich aus. Ich habe 2 Constraint-Steckdosen für diese abgeschnittenen Größen hergestellt.
Dann in viewDidLoad
Funktioniert super.
quelle
Ich habe tagelang versucht, eine Lösung für die Verwendung der AutoLayout-Ansicht einer eingebetteten Bildlaufansicht zu finden, um die Bildlaufansicht auf dem sichtbaren Bildschirm zu zentrieren, der für alle Geräte / Bildschirmabmessungen sowie für die Bildschirmdrehung funktioniert.
Ich habe Tage damit verbracht, es nur mit Autolayout zu versuchen, und bin nah dran, aber nie nah genug dran. Am Ende musste ich also auch 3 Codezeilen pro Bildschirm in viewDidLoad hinzufügen.
Siehe Lösung unten:
Gehen Sie nun zur .m-Datei und fügen Sie diese Codezeilen in viewDidLoad ein (spielen Sie mit dem Füllbetrag, um die richtige Vert-Zentrierung zu erhalten).
{self.constraintVertVtoSV.constant = 150.0; }}
Dies sollte nun auf allen Geräten ausgeführt werden und richtig zentriert sein und trotzdem richtig scrollen.
quelle
Wenn Sie wie ich nur statischen Inhalt ohne Einschränkungen in der Unteransicht verwenden, können Sie Folgendes tun:
quelle
Ähnliches Problem habe ich heute mit iOS 8.4, Xcode 6.4
Dort eine Ansicht mit einer Bildlaufansicht, die eine Inhaltsansicht (UIView) mit Unteransichten enthält.
Alles ist überall automatisch angeordnet. Die Kanten der Bildlaufansicht werden mit Einschränkungen an die Kanten der übergeordneten Ansichten angeheftet. Die Kanten der Inhaltsansicht werden mit Einschränkungen an die Kanten der Bildlaufansicht angeheftet.
Ursprünglich weigerte sich die Inhaltsansicht, die Größe als volle Breite der Bildlaufansicht zu bestimmen. Ich musste der Inhaltsansicht eine zusätzliche Einschränkung hinzufügen, damit ihre Breite mit der übergeordneten Bildlaufansicht übereinstimmt. Oder ich könnte eine contentView.centerX == scrollView.centerX-Einschränkung festlegen. Bei einer dieser Optionen wurde zusätzlich zum Fixieren der Kanten plötzlich die richtige Größe für die Inhaltsansicht festgelegt.
Anheften der Ränder der Inhaltsansicht an die Bildlaufansicht unter Verwendung visueller Einschränkungen des Formulars.
Ich benutze eine Routine, um das Array zu durchlaufen und sie der scrollView hinzuzufügen.
quelle
Ich hatte ein ähnliches Problem. Ich habe alle Einschränkungen festgelegt und mich immer gefragt, warum die Größe einiger Unteransichten immer noch geändert wird. Meine Lösung bestand darin, clipsToBounds auf YES zu setzen.
quelle
In Kürze können Sie diese funktionierende Lösung verwenden.
Einschränkungen
ScrollView
: Führen, Nachlaufen, Oben, Unten = ÜbersichtContentView
: Führend, nachlaufend, oben, unten = ScrollView. Höhe fest / relativ zum Inhalt.Sie können die Breitenbeschränkung (contentView) so einstellen, dass sie der Ansicht der Bildlaufansichten entspricht. Wählen Sie jedoch Entfernen zum Zeitpunkt der Erstellung entfernen, da Sie diese Einschränkung programmgesteuert hinzufügen. Dies ist nur so, damit sich der IB nicht mit Warnungen beschwert.
Und im View Controller
viewDidLayoutSubviews
nenne ich einfach diese Methode:quelle
Ich weiß, dass dies eine Lösung für Laien ist und nicht das, was Apple im Dokument vorschlägt, aber es hat bei mir zweimal funktioniert, mit unterschiedlichen Inhalten und kann sehr schnell eingerichtet werden: Fügen Sie im Storyboard View Controller UIView ein. Fügen Sie in UIView eine Tabellenansicht, Dynamic, 0 Prototype-Zellen, Style Plain oder Grouped ein. Fügen Sie in der Tabellenansicht eine Bildlaufansicht ein, und fügen Sie in der Bildlaufansicht Inhalte ein. Das war's, keine Einstellungen im Custom View Controller.
quelle