623 Stimmen

UIScrollView Scrollable Content Size Ambiguity UIScrollView Größenambiguität des scrollbaren Inhalts

Liebe Entwickler, ich habe Probleme mit AutoLayout in Interface Builder (Xcode 5 / iOS 7). Es ist sehr grundlegend und wichtig, daher denke ich, dass jeder wissen sollte, wie das ordnungsgemäß funktioniert. Wenn dies ein Bug in Xcode ist, ist es ein kritischer!

Also, immer wenn ich eine Ansichtshierarchie wie diese habe, gerate ich in Schwierigkeiten:

>UIViewController
>> UIView
>>>UIScrollView
>>>>UILabel (oder jedes andere vergleichbare UIKit-Element)

Der UIScrollView hat feste Einschränkungen, z.B. 50 px von jeder Seite (kein Problem). Dann füge ich eine Top Space-Einschränkung zum UILabel hinzu (kein Problem) (und ich kann sogar Höhe / Breite des Labels anheften, ändert nichts, sollte aber aufgrund der intrinsischen Größe des Labels unnötig sein)

Die Schwierigkeiten beginnen, wenn ich eine trailing-Einschränkung zum UILabel hinzufüge:

Z.B. Abstand am Ende zu: Superview Gleich: 25

Jetzt treten zwei Warnungen auf - und ich verstehe nicht warum:

A) Scrollbare Inhaltsgrößenambiguität (Scroll View hat eine unklare scrollbare Inhaltsgröße)

B) Falsch platzierte Ansichten (Label Erwartet: x= -67 Tatsächlich: x= 207

Ich habe dieses minimale Beispiel in einem ganz neuen Projekt gemacht, das Sie herunterladen können, und ich habe einen Screenshot angehängt. Wie Sie sehen können, erwartet der Interface Builder, dass das Label außerhalb der Grenze des UIScrollView sitzt (das orangefarbene gestrichelte Rechteck). Das Aktualisieren des Rahmens des Labels mit dem Resolve Issues Tool bewegt es genau dahin.

Bitte beachten Sie: Wenn Sie den UIScrollView durch eine UIView ersetzen, ist das Verhalten wie erwartet (der Rahmen des Labels ist korrekt und gemäß der Einschränkung). Es scheint also entweder ein Problem mit UIScrollView zu geben oder ich übersehe etwas Wichtiges.

Wenn ich die App ausführe, ohne den Rahmen des Labels wie von IB vorgeschlagen zu aktualisieren, wird es genau richtig positioniert, genau dort, wo es sein sollte, und der UIScrollView ist scrollbar. Wenn ich den Rahmen aktualisiere, ist das Label nicht zu sehen und der UIScrollView scrollt nicht.

Hilf mir Obi-Wan Kenobi! Warum das uneindeutige Layout? Warum die falsch platzierte Ansicht?

Sie können das Beispielsprojekt hier herunterladen und sehen, ob Sie herausfinden können, was passiert: https://github.com/Wirsing84/AutoLayoutProblem

Illustration des Problems im Interface Builder

2voto

Menschen, die Probleme mit dem uiscrollview haben, das nicht scrollt, setzen einfach den unteren Abstand des Inhaltsansicht mit dem unteren Layout der letzten Ansicht (die sich innerhalb der Inhaltsansicht befindet). Vergessen Sie nicht, den Center-Y-Abstand zu entfernen.

Alle anderen Einschränkungen sind die gleichen wie oben definiert. Scrollview interessiert sich nur dafür, die maximale Höhe von seiner Inhaltsansicht zu erhalten, und wir setzen sie als unteren Abstand der letzten Ansicht, was bedeutet, dass die Scrollview automatisch ihren Inhaltsversatz ändern wird.

In meinem Fall war die letzte Ansicht ein UILable mit der Eigenschaft der Anzahl von Zeilen = 0 (die automatisch ihre Höhe je nach Inhalt anpasst), so dass sie dynamisch die Höhe des UILable erhöht und schließlich unser scrollbares Gebiet vergrößert, da das untere Layout des UILable mit dem unteren Rand unserer Inhaltsansicht ausgerichtet ist, was die Scrollview dazu zwingt, ihren Inhaltsversatz zu erhöhen.

2voto

Warif Akhand Rishi Punkte 23036

Ich habe ein Video auf YouTube gemacht
ScrollStackViews nur mit Storyboard in Xcode verwenden

Ich denke, es können 2 Arten von Szenarien auftreten.

Die Ansicht innerhalb des ScrollViews -

  1. hat keine intrinsische Inhaltsgröße (z.B. UIView)
  2. hat eine eigene intrinsische Inhaltsgröße (z.B. UIStackView)

Für eine vertikal scrollbare Ansicht müssen in beiden Fällen diese Einschränkungen hinzugefügt werden:

  1. 4 Einschränkungen von oben, links, unten und rechts.

  2. Gleichbreite zum ScrollView (um horizontales Scrollen zu stoppen)

Sie benötigen keine weiteren Einschränkungen für Ansichten, die ihre eigene intrinsische Inhaltsgröße haben.

Bildbeschreibung hier eingeben

Für Ansichten, die keine intrinsische Inhaltsgröße haben, müssen Sie eine Höheneinschränkung hinzufügen. Die Ansicht wird nur scrollen, wenn die Höheneinschränkung größer ist als die Höhe des ScrollViews.

Bildbeschreibung hier eingeben

1voto

Bitcon Punkte 141

Vertikales Scrollen

  1. Füge einen UIScrollView mit Einschränkungen 0,0,0,0 zum Übergeordneten hinzu.
  2. Füge eine UIView im ScrollView hinzu, mit Einschränkungen 0,0,0,0 zum Übergeordneten.
  3. Füge dieselbe Breiteneinschränkung für UIView zu UIScrollView hinzu.
  4. Füge die Höhe zu UIView hinzu.
  5. Füge Elemente mit Einschränkungen zur UIView hinzu.
  6. Für das Element, das am nächsten am unteren Rand liegt, stelle sicher, dass es eine Einschränkung zum unteren Rand von UIView hat.

1voto

mfaani Punkte 28161

Für jede Ansicht sind die Größe des Rahmens und seines Inhalts gleich, d. H. wenn Sie also einen Inhalt (z. B. Bild) mit der Größe von 200 * 800 haben, dann ist auch sein Rahmen 200 * 800.

Dies gilt NICHT für den Inhalt von Scrollviews. Der Inhalt ist normalerweise größer als die Rahmengröße des ScrollViews. Wenn der Inhalt in der Breite gleich ist, scrollen Sie nur vertikal. Wenn die Höhe gleich ist, scrollen Sie nur horizontal. Daher ist es die einzige Ansicht, die 6 Einschränkungen und nicht nur 4 benötigt. Für jede andere Ansicht verursacht mehr als 4 erforderliche Einschränkungen einen Konflikt.


Um Ihr Scrollview, dessen Inhalt und die Position des Scrollens einzurichten, müssen Sie grundsätzlich drei Fragen beantworten:

  1. Wie groß ist mein Rahmen? d. h. Wie groß sollte das ScrollView zu einem bestimmten Zeitpunkt sein? z. B. Ich möchte nur die Hälfte der Bildschirmhöhe verwenden, also

    scrollview.frame = (x: 0, y:0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height / 2)

  2. Wie viel Scrollraum benötige ich? d. h. Wie groß ist der Inhalt? z. B. Der Rahmen kann nur 500 Punkte breit sein, aber dann können Sie ein Bild mit 7000 Punkten einstellen, für das das horizontale Scrollen recht lange dauern würde. Oder lassen Sie es genau 500 Punkte breit sein, was bedeutet, dass kein horizontales Scrollen möglich ist.

  3. Wie weit haben Sie in diesem Moment gescrollt? Angenommen, die Breite Ihres Inhalts (oder Bildes) betrug 7000 und die Rahmengröße beträgt nur 500. Um ans Ende des Bildes zu gelangen, müssten Sie 6500 Punkte nach rechts scrollen. Der dritte Teil beeinflusst die Einschränkungen wirklich nicht. Sie können das vorerst ignorieren. Das Verständnis hilft nur dabei zu verstehen, wie ein ScrollView funktioniert.

Lösung

Im Grunde wird die Layout-Engine beschweren, wenn Sie die 2 zusätzlichen Einschränkungen (zur Größe des Inhalts) auslassen, aufgrund der Unklarheit. Es wird nicht wissen, welcher Bereich des Inhalts versteckt ist (im ScrollView nicht sichtbar) und welcher Bereich des Inhalts nicht (im ScrollView sichtbar) versteckt ist.

Stellen Sie also sicher, dass Sie auch Größeneinschränkungen für den Inhalt hinzufügen. Weitere Informationen dazu finden Sie unter dieser Antwort

Aber manchmal füge ich meinen Ansichten keine Größe Einschränkungen hinzu und es funktioniert einfach. Warum ist das so?

Wenn alle Inhalte, die Sie in das ScrollView eingefügt haben, an den Rändern des ScrollViews eingeschränkt sind, fügt das ScrollView Platz hinzu, um den wachsenden Inhalt aufzunehmen. Es könnte sein, dass Sie UIViews verwenden, deren intrinsicContentSize 0 ist, sodass das ScrollView immer noch über die Unklarheit seines Inhalts bescheidet. Wenn Sie jedoch ein UILabel verwendet haben und es hat einen nicht leeren Text, wird sein intrinsicContentSize (basierend auf Schriftgröße und Textlänge und Zeilenumbrüchen usw.) festgelegt, sodass das ScrollView nicht über seine Unklarheit beschwert.

0voto

nico Punkte 9578

Setzen Sie die Größe des ViewController (derjenige, der das UIScrollView enthält) im Größeninspektor in Interface Builder auf Freiform, dann sollte alles funktionieren.

Freiform-Einstellung im Größeninspektor in Interface Builder für den enthaltenden UIViewcontroller

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X