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

1251voto

Matteo Gobbi Punkte 17025

Aktualisiert

Heutzutage hat Apple das Problem erkannt, das wir vor vielen Jahren gelöst haben (lol_face) und bietet Content Layout Guide und Frame Layout Guide als Teil der UIScrollView an. Daher müssen Sie die folgenden Schritte durchgehen:

  1. Das gleiche wie in der originalen Antwort unten;

  2. Für diesen contentView setzen Sie die oberen, unteren, linken und rechten Ränder auf 0, indem Sie sie an den Content Layout Guide des Scroll Views anheften;

  3. Setzen Sie jetzt die Höhe des contentView auf die Höhe des Frame Layout Guide. Tun Sie dasselbe für die Breite;

  4. Schließlich setzen Sie die Priorität der Höhengleichheitsbeschränkungen auf 250 (falls Sie möchten, dass die Ansicht vertikal scrollt oder die Breite horizontal scrollt).

Fertig.

Jetzt können Sie alle Ihre Ansichten in diesen contentView hinzufügen, und die contentSize des scrollView wird automatisch entsprechend dem contentView angepasst.

Vergessen Sie nicht, die Beschränkung vom unteren Rand des letzten Objekts in Ihrem contentView zu den Rändern des contentView einzustellen.

Original [Veraltet]

Also habe ich es einfach auf diese Weise sortiert:

  1. Fügen Sie innerhalb der UIScrollView eine UIView hinzu (wir können das contentView nennen);

  2. In diesem contentView setzen Sie die oberen, unteren, linken und rechten Ränder auf 0 (natürlich vom scrollView, der der superView ist); Setzen Sie auch die horizontale und vertikale Zentrierung aus;

222voto

Đorđe Nilović Punkte 3322

Xcode 11+

Der einfachste Weg mit autolayout:

  1. Fügen Sie UIScrollView hinzu und heften Sie es 0,0,0,0 am übergeordneten Element an (oder in der gewünschten Größe).
  2. Fügen Sie den Container vom Typ UIView innerhalb des ScrollViews hinzu, heften Sie ihn 0,0,0,0 an allen 4 Seiten und zentrieren Sie ihn horizontal und vertikal.
  3. Ändern Sie im Größeninspektor des Containers die Priorität von unten und vertikal zentrieren auf 250. (für horizontalen Bildlauf ändern Sie rechts und horizontal zentrieren)
  4. Fügen Sie alle Ansichten, die Sie benötigen, in den genannten Container (UIView) ein. Vergessen Sie nicht, die untere Einschränkung auf der untersten Ansicht festzulegen.
  5. Wählen Sie den UIScrollView aus, wählen Sie den Größeninspektor aus und deaktivieren Sie Content-Layoutführungen.

137voto

WantToKnow Punkte 1697

Xcode 11+, Swift 5

Wenn Sie sich fragen, warum alle Antworten nicht mehr funktionieren, stellen Sie sicher, dass Sie die Inhaltsansicht (die Sie im Scrollview platziert haben) an den Inhaltslayoutleitfaden des Scrollview und NICHT an den Rahmenvorgabeleitfaden angeheftet haben.

Die Ränder der Inhaltsansicht (führend, nachlaufend, oben, unten) sollten nicht wie bei der Führung auf dem Bild - am Rahmenvorgabeleitfaden - festgesetzt werden

Nicht so

sondern wie hier - am Inhaltslayoutleitfaden.

Wählen Sie den Inhaltslayoutleitfaden aus dem Dropdown

Bildbeschreibung hier eingeben

Dann werden die meisten Antworten für Sie funktionieren.

Der einfachste Ansatz ist jetzt folgender:

  1. Platzieren Sie das Scrollview im Root-View
  2. Heften Sie alle Seiten des Scrollviews am Übergeordneten View an
  3. Nehmen Sie eine andere UIView (nennen wir sie Inhaltsansicht) und platzieren Sie sie im Scrollview
  4. Heften Sie alle Seiten der Inhaltsansicht am Inhaltslayoutleitfaden des Scrollviews an
  5. Heften Sie die Breite der Inhaltsansicht so fest, dass sie der Rahmenvorgabe des Scrollviews entspricht
  6. Korrigieren Sie die Höhe der Inhaltsansicht auf jede gewünschte Weise (ich habe nur eine konstante Höhenbeschränkung im untenstehenden Beispiel verwendet)

Insgesamt wird Ihre Struktur in der einfachsten Implementierung so aussehen

Bildbeschreibung hier eingeben

104voto

self.name Punkte 2261

Dieser Fehler hat mich eine Weile beschäftigt, zunächst habe ich versucht, die Größe des ScrollView zu fixieren, aber die Fehlermeldung sagt eindeutig "Inhaltsgröße". Ich habe darauf geachtet, dass alles, was ich vom oberen Rand des ScrollView angeheftet habe, auch am unteren Rand angeheftet war. Auf diese Weise kann der ScrollView seine Inhalthöhe berechnen, indem er die Höhe aller Objekte und Einschränkungen findet. Dadurch wurde die unklare Inhalthöhe gelöst, die Breite ist ziemlich ähnlich... Zunächst hatte ich die meisten Dinge X-zentriert im ScrollView, aber ich musste die Objekte auch an die Seite des ScrollView anheften. Das gefällt mir nicht, weil das iPhone6 einen breiteren Bildschirm haben könnte, aber den Fehler "unklare Inhaltsbreite" entfernt.

65voto

skywinder Punkte 20873

Es handelt sich um die Antwort auf meine selbst beantwortete Frage UIScrollView + Zentrierte Ansicht + Ambigous Scrollable Inhaltsgröße + viele iPhone-Größen.

Aber es deckt auch Ihren Fall vollständig ab!

Also, hier ist der Ausgangszustand für den einfachsten Fall:

  1. scrollView mit 0 Einschränkungen zu allen Seiten
  2. Schaltfläche horizontal und vertikal zentriert mit festen Breite und Höhe Einschränkungen
  3. Und natürlich - ärgerliche Warnungen Hat eine unklare scrollbare Inhaltsbreite und Hat eine unklare scrollbare Inhaltsgröße in der Höhe.

1

Alles, was wir tun müssen, ist:

  • Fügen Sie 2 zusätzliche Einschränkungen hinzu, zum Beispiel "0" für trailing und/oder bottom Abstand für unsere Ansicht (schauen Sie sich das Beispiel auf dem Screenshot unten an).

Wichtig: Sie müssen trailing und/oder bottom Einschränkungen hinzufügen. Nicht "leading und top" - das funktioniert nicht!

2

Sie können es in meinem Beispielprojekt überprüfen, das zeigt, wie man dieses Problem behebt.

Nachtrag

Der Logik gemäß sollte diese Aktion zu "widersprüchlichen Einschränkungen" führen. Aber nein!

Icch weiss nicht, warum es funktioniert und wie Xcode erkennt, welche Einschränkung priorisiert ist (weil ich die Priorität für diese Einschränkungen nicht explizit festgelegt habe). Ich wäre dankbar, wenn jemand in den Kommentaren unten erklären könnte, warum es funktioniert.

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