web-dev-qa-db-de.com

Programmatische UIScrollview mit Autolayout

Nachdem ich die technischen Hinweise auf der Apple-Website gelesen und matt neuburgs Buch über das Programmieren von iOS 11 mit einem UIScrollview mit Autolayout gelesen hatte, konnte ich das Konzept der Funktionsweise nicht vollständig verstehen. 

Grundsätzlich möchte ich eine Scrollview haben, die eine untergeordnete Ansicht hätte ChildView, wobei diese untergeordnete Ansicht dann eine Textview hat.

Unten habe ich das Mockup von dem, was ich versuche, programmatisch No-Nibs, keine Storyboards zu erreichen, angehängt.

 enter image description here

und was den Code angeht, so komme ich normalerweise dazu:

Code

let Scroller: UIScrollView = {
    let scroll = UIScrollView()
    scroll.translatesAutoresizingMaskIntoConstraints = false
    scroll.backgroundColor = UIColor.alizarinColor()
    return scroll
}()

// Content view

let ContentView : UIView = {

    let content = UIView()
    content.translatesAutoresizingMaskIntoConstraints = false
    content.backgroundColor = UIColor.blue
    return content
}()

override func viewDidLoad() {

    super.viewDidLoad()

    self.view.addSubview(Scroller)

    // Auto layout
    Scroller.leftAnchor.constraint(equalTo: view.leftAnchor, constant:0).isActive = true
    Scroller.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0).isActive = true
    Scroller.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0).isActive = true
    Scroller.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: 0).isActive = true

    Scroller.addSubview(ContentView)
    // Undefined Content view 
}

Bitte beachten Sie: für ContentView definiere ich normalerweise Randbedingungen, um die Kanten in der Bildlaufansicht zu verankern, aber nicht in diesem Fall mit Autolayout und der Tatsache, dass ich bei der Tastatur becomesFirstResponder vertikal nach oben scrollen möchte. Eine andere Methode, mit der ich arbeiten wollte, bestand darin, eine UIView zu erstellen, die größer als die Bildlaufansicht ist, damit die untergeordnete Ansicht eine Unteransicht dieser größeren Ansicht sein kann, die die Bildlaufansicht als übergeordnetes Element hat.

Mein Problem: Wie kann ich das von nun an erreichen? Irgendwelche Vorschläge? Ich habe darüber nachgedacht: (ContentView wäre die größere Ansicht, die einen Bildlauf zulässt, und die untergeordnete Ansicht wäre die dritte untergeordnete Ansicht in der Hierarchie.)

 enter image description here

9
Samarey

Ich habe sorgfältig die Apple-Dokumentation zu UIScrollView und insbesondere zu ihrer Funktionsweise mit auto layout gelesen. Auch ich bevorzuge den programmatischen Pfad. Erstens müssen Sie keine Faux-Content-Ansicht erstellen. Sie können der Scroll-Ansicht direkt Unteransichten hinzufügen (und ich bevorzuge dies, da ich eine Faux-Ansicht als fremdes Objekt betrachte). Apple, AFAIK, empfiehlt nicht, einen zu erstellen, sondern schlägt lediglich vor, dass Sie es können. Und soweit ich mich erinnere, haben sie Beispiele hervorgebracht, bei denen sie es nicht tun. Zweitens sollten Unteransichten in der Bildlaufansicht (möglicherweise nicht) auf die Bildlaufansicht zurückgreifen, um ihre Breite oder Höhe zu bestimmen. Drittens müssen Ihre Einschränkungen von links nach rechts und von oben nach unten verkettet sein, damit das automatische Layout die Inhaltsansicht für Sie erstellen kann. Die dritte "Regel" kann etwas verwirrend sein oder sogar eingängig erscheinen, aber genau so will Apple, dass Sie Ihre Bildlaufansicht erstellen.

Wenn Sie eine Bildlaufansicht erstellen, können Sie dem Rahmen die Grenzen der Ansicht des Controllers geben:

scrollView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(scrollView)
scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
scrollView.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
scrollView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
scrollView.heightAnchor.constraint(equalTo: view.heightAnchor).isActive = true

Sie müssen dann die Grenzen der Inhaltsansicht festlegen, indem Sie ihre Unteransichten an den Rändern der Bildlaufansicht verankern. Daher muss Ihre oberste Ansicht am oberen Rand der Bildlaufansicht verankert sein und ihre Breite darf die Breite der Bildlaufansicht (dh die Breite der Ansicht) nicht überschreiten (wenn Ihr Ziel nur vertikales Blättern ist).

topMostView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(topMostView)
topMostView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
topMostView.topAnchor.constraint(equalTo: scrollView.topAnchor).isActive = true
topMostView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
topMostView.heightAnchor.constraint(equalToConstant: 1000).isActive = true

Beachten Sie, dass topMostView nicht auf die Bildlaufansicht angewiesen ist, um ihre Größe zu bestimmen (nur ihre Position).

Der Inhalt in Ihrer Bildlaufansicht hat jetzt eine Höhe von 1000, jedoch wird kein Bildlauf ausgeführt, da nichts am unteren Rand der Bildlaufansicht verankert ist. Tun Sie dies daher in Ihrer untersten Ansicht.

bottomMostView.translatesAutoresizingMaskIntoConstraints = false
scrollView.addSubview(bottomMostView)
bottomMostView.leadingAnchor.constraint(equalTo: scrollView.leadingAnchor).isActive = true
bottomMostView.topAnchor.constraint(equalTo: topMostView.bottomAnchor).isActive = true
bottomMostView.widthAnchor.constraint(equalTo: view.widthAnchor).isActive = true
bottomMostView.heightAnchor.constraint(equalToConstant: 1000).isActive = true

bottomMostView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true

Der letzte Anker kann nicht intuitiv erscheinen, weil Sie eine Ansicht verankern, die 1000 Punkte hoch ist, auf einen Anker, den Sie gerade am unteren Rand der Ansicht verankert haben, der definitiv weniger als 1000 Punkte hoch ist. Aber so möchte Apple, dass Sie es tun. Mit diesem Ansatz brauchen Sie nicht nur keine Inhaltsansicht zu erstellen, sondern Sie können tatsächlich vorgeben, dass sie nicht existiert - es sei denn, Sie benötigen natürlich ihre Grenzen, die noch aus den Eigenschaften der Bildlaufansicht gelesen werden können.

Tatsächlich geht dieses Prinzip über die Bildlaufansicht hinaus. Wenn Sie ein benutzerdefiniertes UITableViewCell mit dem automatischen Layout erstellen, verketten Sie Ihre Einschränkungen von links nach rechts und von oben nach unten, wobei die oberste Unteransicht am oberen Rand der Zelle (topMostView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true) und die unterste Unteransicht am unteren Ende verankert ist der Zelle (bottomMostView.topAnchor.constraint(equalTo: self.bottomAnchor).isActive = true) und Sie haben sich selbst ändernde Zellen.

18
bsod

Wenn Sie ein ScrollView erstellen, empfiehlt Apple, ein ContentView darin zu erstellen und diesem Inhalt zu geben. Zeigen Sie die Breite der ViewController-Ansicht an, und fixieren Sie die obere, untere, führende und nachfolgende Einschränkung in die Scrollansicht. Platzieren Sie anschließend Elemente von oben nach unten Das unterste Element am unteren Rand der Inhaltsansicht von scollview einfügen und anheften, damit der Bildlauf seine Höhe darstellen kann. Diese untere Einschränkung kann beliebig sein. Entsprechend wird der Bildlauf fortgesetzt, bis der Bildlauf abgeschlossen ist 

3
Sh_Khan