UIScrollView Scrollable Content Size Ambiguity


510

Kollegen, ich habe Probleme mit AutoLayout in Interface Builder (Xcode 5 / iOS 7). Es ist sehr einfach und wichtig, daher denke ich, dass jeder wissen sollte, wie das richtig funktioniert. Wenn dies ein Fehler in Xcode ist, ist es ein kritischer!

Wenn ich also eine solche Ansichtshierarchie habe, stoße ich auf folgende Probleme:

>UIViewController
>> UIView
>>>UIScrollView
>>>>UILabel (or any other comparable UIKit Element)

Das UIScrollView hat feste Einschränkungen, z. B. 50 Pixel von jeder Seite (kein Problem). Dann füge ich dem UILabel eine Top Space-Einschränkung hinzu (kein Problem) (und ich kann sogar Höhe / Breite des Etiketts anheften, ändert nichts, sollte aber aufgrund der Eigengröße des Etiketts nicht erforderlich sein)

Das Problem beginnt, wenn ich dem UILabel eine nachfolgende Einschränkung hinzufüge:

Beispiel: Leerzeichen nach: Übersicht Gleich: 25

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

A) Mehrdeutigkeit der Größe des scrollbaren Inhalts (Die Bildlaufansicht weist eine mehrdeutige Höhe / Breite des scrollbaren Inhalts auf.)

B) Falsch platzierte Ansichten (Beschriftung erwartet: x = -67 Ist: x = 207

Ich habe dieses minimale Beispiel in einem neuen Projekt gemacht, das Sie herunterladen können, und einen Screenshot angehängt. Wie Sie sehen können, erwartet Interface Builder, dass sich das Label außerhalb der Grenze von UIScrollView befindet (das orange gestrichelte Rechteck). Wenn Sie den Rahmen des Etiketts mit dem Tool zum Beheben von Problemen aktualisieren, wird er genau dorthin verschoben.

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

Wenn ich die App starte, ohne den von IB vorgeschlagenen Rahmen des Labels zu aktualisieren, ist sie genau dort positioniert, wo sie sein soll, und die UIScrollView ist scrollbar. Wenn ich den Frame aktualisiere, ist das Label nicht sichtbar und die UIScrollView scrollt nicht.

Hilf mir, Obi-Wan Kenobi! Warum das mehrdeutige Layout? Warum die verlegte Ansicht?

Sie können das Beispielprojekt hier herunterladen und versuchen, herauszufinden, was los ist: https://github.com/Wirsing84/AutoLayoutProblem

Illustration des Problems in Interface Builder


8
Versuchen Sie, das UILabel in einer Inhaltsansicht zu platzieren, und setzen Sie dann die Hinterkante des Etiketts auf die Inhaltsansicht (reguläre UIView). Dieses Video kann Ihnen sehr helfen: youtube.com/watch?v=PgeNPRBrB18&feature=youtu.be
erdekhayser

1
Tolles Video, aber es hat die Warnungen für mich nicht behoben. :(
Herr Rogers

Vielen Dank für das Video - ich habe (ziemlich überraschend) ziemlich viel daraus gelernt! Wenn ich jedoch das Wissen über das Video mit stackoverflow.com/questions/18953617/… kombiniere, kann ich die Warnungen korrigieren . Die Frage bleibt: Wie kann die contentView-Größe von scrollView nur so groß wie nötig gemacht werden?
Wirsing

Schauen Sie sich dieses Video an. Es zeigt, wie UIScrollLayout und Autolayout mit XCode 5 / iOS 7 verwendet werden.
Jaxvy

Mein Vorschlag ist, nicht UIScrollViewdirekt zu verwenden. Verwenden Sie stattdessen UICollectionViewoder UITableViewso viel wie möglich, meistens ist mit diesem Element alles möglich und es gibt auch Einfachheit, Lesbarkeit und Wiederverwendbarkeit !!!
SPatel

Antworten:


1093

Also habe ich einfach so aussortiert:

  1. Innerhalb des UIScrollView Add a UIView(wir können das nennen contentView);

  2. In dieser contentView, Settop, unteren, linken und rechten Rand auf 0 (natürlich von der scrollViewdem die superView);Stellen Sie auch die Mitte horizontal und vertikal aus .

Fertig .

Jetzt können Sie alle Ihre Ansichten hinzufügen contentView, und die contentSizederscrollView automatisch entsprechend mit der Größe verändert werden contentView.

Aktualisieren:

Einige Sonderfälle werden in diesem Video behandelt, das von @Sergio in den Kommentaren unten gepostet wurde .


33
Fast perfekt, außer dass die Bildlaufansicht die Länge Ihres Inhalts nicht mehr erraten und die Größe entsprechend anpassen kann. Die Inhaltsgröße passt sich den Objekten an. Ich habe eine Tabellenansicht in der Inhaltsansicht, deren Höhe sich ändert (über eine Einschränkung), und in der Bildlaufansicht kann ich nicht scrollen.
CyberMew

28
Vielleicht kann dieses Video helfen, alle verbleibenden Probleme zu überwinden.
Sergio

46
das bringt es nicht dazu, zu scrollen.
Dorian

2
@MatteoGobbi Das war es! Es hat den Trick gemacht! Hatte 2 Tage lang mit solchen Problemen des ScrollView AutoLayout-Wahnsinns zu kämpfen .... Danke, Alter !!!
Polo987

56
Für alle, die Probleme damit haben, dass ScrollView nicht scrollbar ist, war es der Trick für mich, den unteren Rand von contentView festzulegen und die mittleren vertikalen Einschränkungen mit niedriger Priorität auszurichten!
Jimmy0251

98

Es dauerte eine Weile, bis ich diesen Fehler gefunden hatte. Zunächst habe ich versucht, die Größe des ScrollView festzuhalten, aber in der Fehlermeldung steht eindeutig "Inhaltsgröße". Ich habe sichergestellt, dass alles, was ich oben in der ScrollView angeheftet habe, auch unten angeheftet ist. Auf diese Weise kann ScrollView die Höhe des Inhalts berechnen, indem die Höhe aller Objekte und Einschränkungen ermittelt wird. Dies löste die mehrdeutige Höhe des Inhalts, die Breite ist ziemlich ähnlich ... Anfangs hatte ich die meisten Dinge X in der ScrollView zentriert, aber ich musste die Objekte auch an der Seite der ScrollView anheften. Ich mag das nicht, weil das iPhone6 ​​möglicherweise einen breiteren Bildschirm hat, aber den Fehler "Mehrdeutige Inhaltsbreite" beseitigt.


31
Vielen Dank für Ihre Antwort! Wenn ich Sie richtig verstehe, können Sie den Fehler beheben, indem Sie jede einzelne Unteransicht in der ScrollView oben und unten anheften. Dies ist jedoch nicht erforderlich. Sie müssen nur sicherstellen, dass es eine Möglichkeit gibt, eine fortlaufende Reihe von Einschränkungen von oben nach unten in der Bildlaufansicht zu erstellen. [-XXX] Ich hoffe das war verständlich;>
Wirsing

1
Wie kann das Problem behoben werden, wenn die Ansicht eine variable Höhe hat? Wie richte ich dann die Einschränkungen ein, damit die Bildlaufansicht die Größen berechnen kann?
Hashier

2
'Sie müssen nur sicherstellen, dass es eine Möglichkeit gibt, eine durchgehende Reihe von Einschränkungen von oben nach unten in der Bildlaufansicht zu erstellen.' <- danke für diesen Satz
Adam Waite

3
Was mir geholfen hat, war sicherzustellen, dass die Bildlaufansicht an der Übersicht und nicht an den oberen oder unteren Layout-Anleitungen befestigt war. Ich habe die Einschränkung für die untere Layoutanleitung entfernt und anstelle des Interface Builders das Menü durchgegangen. Editor -> Pin -> Bottom Space to Superview.
Alberto Lopez

2
Wenn Sie möchten, dass die Breite der Bildlaufansicht der Breite des Bildschirms Ihres Telefons oder eines anderen Elements in Ihrer Benutzeroberfläche (wie dem enthaltenen UIView) folgt, müssen Sie "gleiche Breite" festlegen, indem Sie ein anderes Element verwenden, das sich außerhalb der Bildlaufansicht befindet.
Departamento B

89

Xcode 11+

Der einfachste Weg mit autolayout:

  1. Fügen Sie UIScrollViewes hinzu 0,0,0,0und heften Sie es an die Übersicht (oder Ihre gewünschte Größe).
  2. Fügen Sie UIViewin ScrollView hinzu, stecken Sie es 0,0,0,0an alle 4 Seiten und zentrieren Sie es horizontallyund vertically.
  3. Ändern Sie im Größeninspektor bottomund die align center YPriorität auf 250. (für horizontalen Bildlaufwechsel trailingund align center X)
  4. Fügen Sie dieser Ansicht alle benötigten Ansichten hinzu. Vergessen Sie nicht, die unterste Einschränkung für die niedrigste Ansicht festzulegen.
  5. Wählen Sie die aus UIScrollView, wählen Sie den Größeninspektor aus und deaktivieren Sie die Option Content Layout Guides.

1
Ich konnte die Inhaltshöhe der Bildlaufansicht nicht einstellen, aber es funktioniert. :)
Blind Ninja

2
Hinweis: Bei mir hat es nur funktioniert, wenn ich die Mitte horizontal und vertikal entfernt und durch die gleiche Breite ersetzt habe (scrollView + Ansicht in scrollView) UND die Höhe basierend auf dem Inhalt hinzugefügt habe, was bedeutet, dass das letzte Element der Ansicht eine untere Einschränkung benötigt. Weitere Informationen finden Sie hier: stackoverflow.com/a/54577278/5056173
Sean Stayns

1
Sean, ich benutze das buchstäblich jeden Tag und ich hatte nie ein Problem mit diesem Ansatz, wenn es um vertikales und horizontales Scrollen in der Bildlaufansicht geht. Vielleicht haben Sie vergessen, eine unterste Einschränkung für das niedrigste / letzte Element festzulegen. Ohne das wird das nicht funktionieren.
Đorđe Nilović

7
Punkt Nummer 4 - zweiter Satz ist der große.
Nitish

2
Diese Antwort hat perfekt für mich
funktioniert

63

Es ist die Antwort auf meine selbst beantwortete Frage UIScrollView + Centered View + Ambigous Scrollable Content Size + viele iPhone-Größen .

Aber es deckt auch Ihren Fall vollständig ab!

Hier ist also der Ausgangszustand für den einfachsten Fall:

  1. scrollView mit 0 Einschränkungen für alle Kanten
  2. Schaltflächenzentriert horizontal und vertikal mit festen Einschränkungen für Breite und Höhe
  3. Und natürlich - nervige Warnungen Has ambiguous scrollable content width und Has ambiguous scrollable content height.

1

Alles was wir tun müssen ist:

  • Fügen Sie 2 zusätzliche Einschränkungen hinzu, z. B. "0" für den nachgestellten und / oder unteren Bereich für unsere Ansicht (siehe Beispiel auf dem Screenshot unten).

Wichtig: Sie müssen nachgestellte und / oder untere Einschränkungen hinzufügen . Nicht "führend und top" - es funktioniert nicht!

2

Sie können es in meinem Beispielprojekt überprüfen , das zeigt, wie dieses Problem behoben werden kann.

PS

Laut Logik sollte diese Aktion "widersprüchliche Einschränkungen" verursachen. Aber nein!

Ich weiß nicht, warum es funktioniert und wie Xcode erkennt, welche Einschränkung mehr Priorität hat (da ich für diese explizite Einschränkung keine Priorität festgelegt habe). Ich bin dankbar, wenn jemand erklärt, warum es in den Kommentaren unten funktioniert.


Toller Tipp!
Dean

Beeindruckend! Das macht im Ernst keinen Sinn, funktioniert aber! Vielen Dank! Das letzte Element, das ich in meiner Ansicht habe, habe ich eine untere Einschränkung von 0 und BANG festgelegt. Endlich funktioniert.
Jakob Hviid

60

Xcode 11+, Swift 5

Wenn Sie sich fragen, warum nicht alle Antworten mehr funktionieren, stellen Sie sicher, dass Sie die Inhaltsansicht (die Sie in die Bildlaufansicht eingefügt haben) im Inhaltslayout-Handbuch der Bildlaufansicht und NICHT im Rahmenlayout-Handbuch angeheftet haben.

Die Kanten der Inhaltsansicht (führende, nachfolgende, obere, untere) sollten nicht wie die führenden im Bild fixiert sein - zum Rahmenlayout-Handbuch

So nicht

aber so - zum Inhaltslayout-Handbuch.

Wählen Sie Content Layout Guide aus der Dropdown-Liste

Geben Sie hier die Bildbeschreibung ein

Und dann funktionieren die meisten Antworten für Sie.

Der einfachste Ansatz sieht jetzt so aus:

  1. Fügen Sie die Bildlaufansicht in die Stammansicht ein
  2. Stecken Sie alle Seiten der Bildlaufansicht in die Übersicht
  3. Nehmen Sie eine andere UIView (nennt sie Inhaltsansicht) und fügen Sie sie in die Bildlaufansicht ein
  4. Pin alle Seiten der Inhaltsansicht, um die Inhaltslayout-Anleitung der Bildlaufansicht zu scrollen
  5. Stecken Sie die Breite der Inhaltsansicht so fest, dass sie der Rahmenlayoutanleitung der Bildlaufansicht entspricht
  6. Korrigieren Sie die Höhe der Inhaltsansicht wie gewünscht (im folgenden Beispiel habe ich nur eine konstante Höhenbeschränkung verwendet).

Insgesamt sieht Ihre Struktur in der einfachsten Implementierung so aus

Geben Sie hier die Bildbeschreibung ein


@WantToKnow Keine Notwendigkeit, die Einschränkung für die Höhe zu nehmen, ändern Sie einfach seine Priorität auf niedrig (250)
Reckoner

Xcode 11+, Swift 5. Laut @WantToKnow-Antwort habe ich mein Problem gelöst und [Video] [1] und [Code] [2] [1] vorbereitet: youtube.com/watch?v=qMrH5_Yj5hM [2]: github.com/AhmAbdallah/CustomCollectionView
Ahmed Abdallah

1
Dies ist eine großartige Antwort, danke.
Konstantin

1
Das ist die richtige Antwort. Vielen Dank.
Vincent Joy

Dies funktionierte nur für mich, als ich dem letzten Element der Inhaltsansicht die untere Einschränkung hinzufügte
D.Zotov

49

Sie müssen eine UIViewals Unteransicht der folgenden erstellen UIScrollView:

  • UIViewController
  • UIView 'Hauptansicht'
    • UIScrollView
      • UIView 'Containeransicht'
        • [Dein Inhalt]

Der zweite Schritt besteht darin, die UIScrollViewEinschränkungen vorzunehmen . Ich habe dies mit den oberen, unteren, führenden und nachfolgenden Einschränkungen für die SuperView getan.

Als nächstes habe ich die Einschränkungen für den Container von hinzugefügt UIScrollViewund hier beginnt das Problem. Wenn Sie dieselben Einschränkungen festlegen (oben, unten, vorne und hinten), gibt das Storyboard eine Warnmeldung aus:

"Mehrdeutige scrollbare Inhaltsbreite" und "Mehrdeutige scrollbare Inhaltshöhe"

Fahren Sie mit den oben genannten Einschränkungen fort und fügen Sie die Einschränkungen Equal Heightund Equal WidthIhre Containeransicht in Bezug auf die Hauptansicht und nicht auf Ihre hinzu UIScrollView. Mit anderen Worten, die Einschränkungen der Containeransicht sind an die UIScrollViewÜbersicht des Containers gebunden .

Danach haben Sie keine Warnungen mehr in Ihrem Storyboard und können die Einschränkungen für Ihre Unteransichten hinzufügen.


2
Einverstanden - Ich denke, das Hinzufügen einer Containeransicht ist die beste und am besten zu wartende Lösung.
Andrew Ebling

1
Diese Lösung funktioniert, wenn Sie keine Navigationsleiste verwalten müssen.
Leena

26

Ich hatte das gleiche Problem. Deaktivieren Sie dieses Kontrollkästchen. Da Sie die Inhaltsgröße im Code einstellen. Geben Sie hier die Bildbeschreibung ein


24

Ich habe es endlich herausgefunden, ich hoffe das ist leichter zu verstehen.

Sie können diese Warnung häufig umgehen, indem Sie der Bildlaufansicht eine Basis-UIView als "Inhaltsansicht" hinzufügen, wie bereits erwähnt, und dieselbe Größe wie Ihre Bildlaufansicht festlegen und in dieser Inhaltsansicht diese 6 Parameter festlegen.

Geben Sie hier die Bildbeschreibung ein

Wie Sie sehen können, benötigen Sie insgesamt 6 Parameter! Unter normalen Umständen duplizieren Sie zwei Einschränkungen, aber auf diese Weise können Sie diesen Storyboard-Fehler vermeiden.


1
Das obige hat bei mir fast funktioniert, da ich mir Sorgen um 3 verschiedene Bildschirmbreiten mache (4/5, 6, 6+). Ich habe die Inhaltsansicht und die Bildlaufansicht auf gleiche Breiten eingestellt. Sie haben Recht, es ist ein Duplikat, da ich der Inhaltsansicht bereits gesagt habe, dass 0 führende und endende Leerzeichen vorhanden sein sollen.
Stuart P.

8
Sie können anstelle von konstanten Werten gleiche Einschränkungen für Breite und Höhe von der Inhaltsansicht zur Bildlaufansicht festlegen. Dies funktioniert bei allen Auflösungen.
Kumar C

Ich muss dasselbe implementieren. Können Sie mir also helfen, dass ich sowohl für die Inhaltsansicht als auch für die Bildlaufansicht die gleiche Höhe und Breite festlegen muss?
Urmi

Es könnte sich lohnen, zu überprüfen, ob Sie dies noch tun müssen. Ich habe kürzlich eine Bildansicht in einer Bildlaufansicht eingerichtet und konnte nur die 4 oben angezeigten Einschränkungen festlegen, damit der Fehler in Xcode 8.3
William T

1
@Honey dies wurde vor über 3 Jahren gepostet. Seitdem haben sie die Storyboards definitiv verbessert. Mir ist auch aufgefallen, dass Sie jetzt ohne die Inhaltsansicht davonkommen können. Ich werde meine Antwort anpassen.
William T.

16

Ich weiß, dass ich vielleicht zu spät komme, aber die nächste Lösung löst diese Art von Problemen ohne zusätzlichen Code , indem ich nur Storyboards verwende:

Für Ihre Inhaltsansicht müssen Sie Einschränkungen für führende / nachfolgende / obere / untere Bereiche für die Bildlaufansicht festlegen. Dadurch wird der Rahmen für die Inhaltsansicht nicht geändert wie :Geben Sie hier die Bildbeschreibung ein

Natürlich müssen Sie zusätzliche Einschränkungen für die Inhaltsansicht erstellen, damit die Bildlaufansicht die Inhaltsgröße kennt. Zum Beispiel feste Höhe und Mitte x einstellen.

Hoffe das hilft.


7

Für mich hat das Hinzufügen eines contentViewnicht wie vorgeschlagen funktioniert. Darüber hinaus entsteht aufgrund der hinzugefügten Ansicht ein Overhead (obwohl ich dies nicht als großes Problem betrachte). Was für mich am besten funktionierte, war nur, die Mehrdeutigkeitsprüfung für meine auszuschaltenscrollView . Alles ist gut angelegt, daher denke ich, dass es in einfachen Fällen wie meinem in Ordnung ist. Beachten Sie scrollViewjedoch, dass der Interface-Builder Sie bei weiteren Einschränkungen für Ihre Unterbrechung nicht mehr davor warnt.

Geben Sie hier die Bildbeschreibung ein


5
Dadurch wird nur die Warnung entfernt und das Problem wird nicht behoben.
Predrag Manojlovic

Du. sind. meine. Held. Wusste nicht, dass dies existiert und freue mich, es zu finden! Ich habe versucht, "Nur Position überprüfen", von dem Sie erwarten würden, dass ich nur die Position überprüfe, aber nein, es erlaubt auch dieses fehlerhafte Problem mit der "Inhaltsgröße". Muss mit "Never Verify" gehen. Vielen Dank!
Dustin

Ich denke, dies ist die richtige Antwort, wenn Sie die untergeordnete Ansicht programmgesteuert erstellen. Vielen Dank!
Florian Kusche


3

Siehe unten: Inhaltsansicht in vertikal und horizontal zentralisierter Bildlaufansicht. Wenn Sie einen Mehrdeutigkeitsfehler erhalten haben, stellen Sie immer sicher, dass zwei aus Ihrer Inhaltsansicht in die Bildlaufansicht eingefügte Elemente 1) .Button Space to Container.2) Trailing Space to Constraint sind, das im Screenshot hervorgehoben ist.

Diese Einschränkung bedeutet beim Scrollen, wie viel Sie nach der Höhe oder Breite Ihrer Inhaltsansicht scrollen können.

Geben Sie hier die Bildbeschreibung ein

es kann dir helfen.


3

Ich habe diese Art von Problem für meine Ansicht gelöst, indem ich "Automatische Layoutprobleme beheben"> "Fehlende Einschränkungen hinzufügen" für die ausgewählte Ansicht verwendet habe Geben Sie hier die Bildbeschreibung ein

Die folgenden zwei Einschränkungen lösen mein Problem:

trailing = Stack View.trailing - 10
bottom = Stack View.bottom + 76

in dem: trailing, bottom sind die trailing, bottom von UIScrollView


Dies funktionierte für mich, indem eine "to bottom" -Einschränkung hinzugefügt wurde. Jetzt, wo ich darüber nachdenke, macht es vollkommen Sinn.
SilverWolf - Stellen Sie Monica am

3

Verwendung content ( UView) als Behälter innen UIScrollView, Stick Kanten ( top, bottom, trailing, leading) von Super ( UIScrollView) und contentViewsollte equalwidthund equalheightzu Super. Das sind Einschränkungen. Und Aufruf der Methode:

-(void)viewDidLayoutSubviews
{
    [super viewDidLayoutSubviews];
    self.scrollView.contentSize = self.contentView.frame.size;
}

Probleme für mich gelöst.


3

Schneller 4+ Ansatz:

1) Setzen Sie den oberen, unteren, linken und rechten Rand von UIScrollView auf 0

2) Fügen Sie in UIScrollView ein UIView hinzu und setzen Sie die oberen, unteren, führenden und nachfolgenden Ränder auf 0 (gleich den UIScrollView-Rändern).

3) Der wichtigste Teil ist das Festlegen von Breite und Höhe, wobei die Höhenbeschränkung eine niedrige Priorität haben sollte .

private func setupConstraints() {

    // Constraints for scrollView
    scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
    scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
    scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

    // Constraints for containerView
    containerView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
    containerView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    containerView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
    containerView.trailingAnchor.constraint(equalTo: scrollView.trailingAnchor).isActive = true
    containerView.widthAnchor.constraint(equalTo: scrollView.widthAnchor).isActive = true

    let heightConstraint = containerView.heightAnchor.constraint(equalTo: scrollView.heightAnchor)
    heightConstraint.priority = UILayoutPriority(rawValue: 250)
    heightConstraint.isActive = true
}

2

Die Antwort von @Matteo Gobbi ist perfekt, aber in meinem Fall kann die Bildlaufansicht nicht gescrollt werden. Ich entferne " Mitte Y ausrichten " und füge " Höhe> = 1 " hinzu. Die Bildlaufansicht wird scrollbar


2

Personen, die mit uiscrollview zu kämpfen haben und nicht scrollen, legen einfach die untere Einschränkung Ihrer Inhaltsansicht mit dem unteren Layout Ihrer letzten Ansicht fest (das sich innerhalb Ihrer Inhaltsansicht befindet). Vergessen Sie nicht, die mittlere Y-Einschränkung zu entfernen.

Rest alle Einschränkungen sind die gleichen wie oben definiert. In der Bildlaufansicht geht es nur darum, die maximale Höhe aus der Inhaltsansicht zu erhalten, und wir legen sie als unterste Einschränkung der letzten Ansicht fest. Dies bedeutet, dass die Bildlaufansicht automatisch den Inhaltsversatz ändert.

In meinem Fall war die letzte Ansicht UILable mit der Eigenschaft no 0 = 0 (wodurch die Höhe automatisch abhängig vom Inhalt angepasst wird), sodass die Höhe von uilable dynamisch erhöht wird und schließlich unser scrollbarer Bereich zunimmt, da das untere Layout von uilable am unteren Rand unserer Inhaltsansicht ausgerichtet ist. Dadurch wird die Bildlaufansicht gezwungen, den Inhaltsversatz zu erhöhen.


2

Ich habe ein Video auf youTube gemacht
Scroll StackViews erstellt, in dem nur Storyboard in Xcode verwendet wurde

Ich denke, dass hier zwei Arten von Szenarien auftreten können.

Die Ansicht in der scrollView -

  1. hat keinen intrinsischen Inhalt Größe (zB UIView)
  2. hat seinen eigenen Inhalt Größe (zB UIStackView)

Für eine vertikal scrollbare Ansicht müssen Sie in beiden Fällen die folgenden Einschränkungen hinzufügen:

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

  2. Gleiche Breite wie die Bildlaufansicht (um das horizontale Bildlauf zu beenden)

Sie benötigen keine weiteren Einschränkungen für Ansichten, die eine eigene Inhaltshöhe haben.

Geben Sie hier die Bildbeschreibung ein


Für Ansichten ohne intrinsische Inhaltshöhe müssen Sie eine Höhenbeschränkung hinzufügen. Die Ansicht wird nur gescrollt, wenn die Höhenbeschränkung größer als die Höhe der scrollView ist.

Geben Sie hier die Bildbeschreibung ein


2
import UIKit

class ViewController: UIViewController {

    //
    let scrollView: UIScrollView = {

        let sv = UIScrollView()
        sv.translatesAutoresizingMaskIntoConstraints = false
        return sv
    }()

    let lipsumLbl: UILabel = { // you can use here any of your subview

        let lbl = UILabel()
        lbl.translatesAutoresizingMaskIntoConstraints = false
        lbl.text = """
        Lorem ipsum dolor sit amet, consectetur adipiscing elit. Fusce eleifend nisi sit amet mi aliquet, ut efficitur risus pellentesque. Phasellus nulla justo, scelerisque ut libero id, aliquet ullamcorper lectus. Integer id iaculis nibh. Duis feugiat mi vitae magna tincidunt, vitae consequat dui tempor. Donec blandit urna nec urna volutpat, sit amet sagittis massa fringilla. Pellentesque luctus erat nec dui luctus, sed maximus urna fermentum. Nullam purus nibh, cursus vel ex nec, pulvinar lobortis leo. Proin ac libero rhoncus, bibendum lorem sed, congue sapien. Donec commodo, est non mollis malesuada, nisi massa tempus ipsum, a varius quam lorem vitae nunc.

        Cras scelerisque nisi dolor, in gravida ex ornare a. Interdum et malesuada fames ac ante ipsum primis in faucibus. Maecenas vitae nisl id erat sollicitudin accumsan sit amet viverra sapien. Etiam scelerisque vulputate ante. Donec magna nibh, pharetra sed pretium ac, feugiat sit amet mi. Vestibulum in ipsum vitae dui vehicula pulvinar eget ut lectus. Fusce sagittis a elit ac elementum. Fusce iaculis nunc odio, at fermentum dolor varius et. Suspendisse consectetur congue massa non gravida. Sed id elit vitae nulla aliquam euismod. Pellentesque accumsan risus dolor, eu cursus nibh semper id.

        Vestibulum vel tortor tellus. Suspendisse potenti. Pellentesque id sapien eu augue placerat dictum. Fusce tempus ligula at diam lacinia congue in ut metus. Maecenas volutpat tellus in tellus maximus imperdiet. Integer dignissim condimentum lorem, id luctus nisi maximus at. Nulla pretium, est sit amet mollis eleifend, tellus nulla viverra dolor, ac feugiat massa risus a lectus. Pellentesque ut pulvinar urna, blandit gravida ipsum. Nullam volutpat arcu nec fringilla auctor. Integer egestas enim commodo, faucibus neque ac, rutrum magna. Vivamus tincidunt rutrum auctor. Cras at rutrum felis. Fusce elementum lorem ut pharetra venenatis.
        """
        lbl.textColor = .darkGray
        lbl.font = UIFont.systemFont(ofSize: 16)
        lbl.numberOfLines = 0
        return lbl
    }()

    //======================================================================//
    //
    // MARK:- viewDidLoad
    //
    override func viewDidLoad() {
        super.viewDidLoad()

        setupViews()
        setupAutoLayout()
    }

    func setupViews() {

        title = "ScrollView Demo"
        view.backgroundColor = .white
        view.addSubview(scrollView)
        scrollView.addSubview(lipsumLbl)
    }

    func setupAutoLayout() {

        scrollView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        scrollView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true

        lipsumLbl.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
        lipsumLbl.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
        lipsumLbl.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
        lipsumLbl.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true
        lipsumLbl.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true
    }
}

Ausgabe:

Geben Sie hier die Bildbeschreibung ein


Warum brauchst du LeadingAnchor, wenn du Anchor bereits verlassen hast?
ShadeToD

leftAnchor kann nicht für diesen Zweck verwendet werden, daher müssen wir LeadingAnchor verwenden, um dasselbe zu erreichen.
iAj

Sie haben beide in Ihrem Beispiel verwendet.
ShadeToD

@ ShadeToD lassen Sie mich überprüfen
iAj

2

In meinem Fall habe ich das Problem mit der falschen Inhaltsgröße und der Mehrdeutigkeit der Inhaltsgröße auf dem iPad erhalten, funktionierte jedoch im Falle des iPhone. Ich habe die folgenden Änderungen im Storyboard vorgenommen, um das Problem zu beheben.

  1. Fügen Sie in UIView eine Bildlaufansicht hinzu und fügen Sie 0,0,0,0 die führenden, oberen, hinteren und unteren Einschränkungen hinzu.
  2. Stellen Sie die Höhe der Bildlaufansicht gemäß den Anforderungen für z. 100.
  3. Fügen Sie UIView hinzu, um die Ansicht zu scrollen, und fügen Sie Einschränkungen hinzu, die nach oben, oben, nach unten und unten zu 0,0,0,0 führen, und richten Sie die Einschränkungen für Mitte (X) und Mitte (Y) aus.
  4. Deaktivieren Sie "Inhaltslayout-Anleitungen" im Größeninspektor der Bildlaufansicht.

1

Vertikales Scrollen

  1. Fügen Sie der Übersicht eine UIScrollView mit den Einschränkungen 0,0,0,0 hinzu.
  2. Fügen Sie in ScrollView eine UIView mit den Einschränkungen 0,0,0,0 für die Übersicht hinzu.
  3. Fügen Sie UIScrollView dieselbe Breitenbeschränkung für UIView hinzu.
  4. Höhe zu UIView hinzufügen.
  5. Fügen Sie der UIView Elemente mit Einschränkungen hinzu.
  6. Stellen Sie für das Element, das dem unteren Bereich am nächsten liegt, sicher, dass es eine Einschränkung für den unteren Bereich von UIView aufweist.

0

Ich habe eine separate Inhaltsansicht erstellt, wie hier gezeigt.

Die Inhaltsansicht ist Freiform und kann alle Unteransichten mit ihren eigenen Einschränkungen in Bezug auf die Inhaltsansicht hinzufügen.

Die UIScrollView wird dem Hauptansichts-Controller hinzugefügt.

Programmatisch füge ich die über IBOutlet verknüpfte contentView zur Klasse hinzu und setze die contentView von UIScrollView.

UIScrollView mit ContentView über Interface Builder


0

Ich habe den gleichen Fehler erhalten. Ich habe folgendes getan

  1. Ansicht (Übersicht)
  2. ScrollView 0,0,6600,600
  3. UIView in ScrollView: 0,0,6600,600
  4. UIView enthält Bildansicht, Beschriftung

Fügen Sie nun führend / nachlaufend / oben / unten für scrollView (2) und dann UIView (3) hinzu.

Wählen Sie Ansicht (1) und Ansicht (3), stellen Sie Größe und Gewicht gleichermaßen ein. Es hat mein Problem gelöst.

Ich habe das Video gemacht, das helfen wird:

https://www.youtube.com/watch?v=s-CPN3xZS1A


0

[getestet in XCode 7.2 und für iOS 9.2]

Was die Storyboard-Fehler und Warnungen für mich unterdrückte, war das Festlegen der Größe der Bildlaufansicht und der Inhaltsansicht (in meinem Fall einer Stapelansicht) auf Platzhalter . Diese Einstellung finden Sie im Größeninspektor im Storyboard. Und es heißt: - Das Festlegen einer intrinsischen Inhaltsgröße für die Entwurfszeit wirkt sich nur auf eine Ansicht während der Bearbeitung in Interface Builder aus. Die Ansicht hat zur Laufzeit nicht diese intrinsische Inhaltsgröße.

Ich denke, wir machen nichts falsch, wenn wir dies einstellen.

Hinweis: Im Storyboard habe ich alle Kanten der Bildlaufansicht an die Übersicht und alle Kanten der Stapelansicht an die Bildlaufansicht angeheftet. In meinem Code habe ich die translatesAutoresizingMaskIntoConstraints sowohl für die Bildlaufansicht als auch für die Stapelansicht als false festgelegt. Und ich habe keine Inhaltsgröße erwähnt. Wenn die Stapelansicht dynamisch wächst, stellen die im Storyboard festgelegten Einschränkungen sicher, dass der Stapel scrollbar ist.

Die Storyboard-Warnung machte mich verrückt und ich wollte die Dinge nicht horizontal oder vertikal zentrieren, nur um die Warnung zu unterdrücken.


0

Wenn jemand ein Verhalten bekommt, bei dem Sie die Bildlaufleiste auf der rechten Seite bemerken, der Inhalt sich jedoch nicht bewegt, ist diese Tatsache wahrscheinlich eine Überlegung wert:

Sie können auch Einschränkungen zwischen dem Inhalt der Bildlaufansicht und Objekten außerhalb der Bildlaufansicht verwenden, um eine feste Position für den Inhalt der Bildlaufansicht bereitzustellen, sodass dieser Inhalt über der Bildlaufansicht zu schweben scheint.

Das ist aus Apples Dokumentation . Wenn Sie beispielsweise versehentlich Ihre oberste Beschriftung / Schaltfläche / Bild / Ansicht an die Ansicht außerhalb des Bildlaufbereichs (möglicherweise eine Kopfzeile oder etwas direkt über der Bildlaufansicht?) Anstelle der Inhaltsansicht angeheftet haben, frieren Sie Ihre gesamte Inhaltsansicht ein.


0

Wie in den vorherigen Antworten erwähnt, sollten Sie der Bildlaufansicht eine benutzerdefinierte Ansicht hinzufügen:

Die benutzerdefinierte Ansicht ist die im Bild markierte Inhaltsansicht

Fügen Sie der Inhaltsansicht alle Ihre Unteransichten hinzu. Irgendwann wird eine Bildlaufinhaltsansicht mit einer mehrdeutigen Warnung zur Inhaltsgröße angezeigt. Wählen Sie die Inhaltsansicht aus, klicken Sie auf die Schaltfläche "Probleme mit dem automatischen Layout beheben" (in der unteren rechten Ecke des IB-Layouts) und wählen Sie "Fehlende hinzufügen" Einschränkungen "Option.

Geben Sie hier die Bildbeschreibung ein

Von nun an aktualisiert die Bildlaufansicht beim Ausführen des Projekts automatisch die Inhaltsgröße, ohne dass zusätzlicher Code erforderlich ist.


0

Sie müssen nur sicherstellen, dass es eine Möglichkeit gibt, eine fortlaufende Reihe von Einschränkungen von oben nach unten in der Bildlaufansicht zu erstellen. [-XXX]

In meinem Fall - einer horizontal scrollenden Bildlaufansicht - musste ich außerdem für jedes untergeordnete Element der Bildlaufansicht Einschränkungen hinsichtlich Breite und Höhe hinzufügen, obwohl der technische Hinweis von Apple dies nicht angibt.



0

Wenn Sie immer noch Probleme mit UIScrollView haben, schalten Sie einfach ab Inhalt - Layout Guides (Wählen Sie ein Scroll in Xcode Interface Builder -> Größe Inspektor in der rechten Panel wählen -> Auswahl aufheben 'Content - Layout Guides') Oder versuchen Sie diese Schritte: Xcode 11 scroll Ansichtslayouts - Dies kann für neue Layoutstile hilfreich sein. Funktioniert gut unter macOS 10.15.2, Xcode 11.3.1, für den 05.02.2020

siehe Screenshot


0

Verwenden von Autolayout

Fügen Sie Ihre Bildlaufansicht in einer genau definierten Ansicht hinzu und fügen Sie dann die Stapelansicht in der Bildlaufansicht hinzu

Fügen Sie den relevanten Superansichten Einschränkungen für oben, links, rechts, unten, Mitte X und Mitte Y aus der Bildlaufansicht und der Stapelansicht hinzu

Stellen Sie sicher, dass Einschränkungen von der Stapelansicht mit der rechtmäßigen Übersicht (Bildlaufansicht) verknüpft sind, da die aktuelle Standardeinstellung darin besteht, eine Einschränkung "Obere Ausrichtung ausrichten" und keine Einschränkung für den oberen Bereich hinzuzufügen.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.