web-dev-qa-db-de.com

Swift UIScrollView - korrekte Implementierung nur für vertikales Scrollen

Ich entschuldige mich im Voraus, da ich sagen würde, dass ich ein Anfänger der iOS-Programmierung bin.

Ich möchte UIScrollView verwenden, da der anzuzeigende Inhalt die Höhe des Bildschirms überschreitet ..__ Daher möchte ich nur einen vertikalen Bildlauf und keinen horizontalen Bildlauf.

Ich verwende das Storyboard, um die Ansichten mit AutoLayout zu zeichnen.

Hier ist der Screenshot meines UIViewController mit dem UIScrollView:

enter image description hereenter image description here

Dann ändere ich das Label in einen solchen großen Text

override func viewDidLoad() {
    super.viewDidLoad()

    self.label1Label.text = "Seize jours après la chute du président Blaise Compaoré, le Burkina Faso a un nouveau chef d'EtatA l'issue d'ultimes tractions, civils et militaires se sont accordés, lundi 17 novembre, sur le nom du diplomate Michel KafandoSeize jours après la chute du président Blaise Compaoré, le Burkina Faso a un nouveau chef d'EtatA l'issue d'ultimes tractions, civils et militaires se sont accordés, lundi 17 novembre, sur le nom du diplomate Michel Kafando"
    self.label1Label.numberOfLines = 0
    self.label1Label.sizeToFit()

Mein Problem ist, dass der Bildlauf horizontal und nicht vertikal verläuft, wenn ich nicht manuell eine Breite für meine Inhaltsansicht (innerhalb von UIScrollView) setze. (Siehe Screenshot unten):

enter image description here

Ich habe versucht, contentSize so einzustellen, wie ich es bei vielen Google-Posts gesehen habe, aber ohne Erfolg:

self.scrollView.contentSize = CGSizeMake(400.0, 600.0)

Wenn ich manuell eine Breite für meine Inhaltsansicht (i.e : 320pts) setze, wird der Bildlauf vertikal (GOOD) durchgeführt. Abhängig von der iPhone-Größe wird jedoch nicht die gesamte Bildschirmbreite abgedeckt, wie im folgenden Screenshot gezeigt:

enter image description here

Die Frage ist: Was ist die richtige Implementierung, um UIScrollView zu verwenden, um ein contentView zu haben, das die Autolayout-Einschränkung (full screen : 0top - 0bottom - 0left - 0right) und das Scrollen nur vertikal berücksichtigt.

Vielen dank für Deine Hilfe!

14
fabdarice

Mike Woelmer zeigt mit Interface Builder im Atomic Object-Blog, wie man das richtig macht. 

http://spin.atomicobject.com/2014/03/05/uiscrollview-autolayout-ios/

Ich habe auch nur meinen eigenen Code (keine Storyboard-Implementierung) auf Github.

https://github.com/nadthevlad/AutolayotScrollview

Sie möchten nicht die Höhe oder Breite Ihres Inhalts oder Ihrer Ansichten einstellen. Stattdessen möchten Sie mithilfe der Pins und Einschränkungen von Autolayouts festlegen, wie sich die Bildlaufansicht verhält. 

  1. Erstellen Sie Ihre UIScrollView * scrollView.

  2. Sie möchten eine UIView * contentView erstellen, in die Sie die restlichen Ansichtselemente einfügen.

    [self.view addSubview:scrollView];
    [scrollView addSubview:contentView];
    [contentView addSubview:_label1];
    [contentView addSubview:_label2];
    [contentView addSubview:_label3];
    [contentView addSubview:_label4];
    [contentView addSubview:_label5];
    [contentView addSubview:_label6];
    
  3. Befestigen Sie die 4 Kanten von scrollView an den 4 Kanten von self.view

  4. Befestigen Sie den oberen und unteren Rand von contentView am oberen und unteren Rand von scrollView.

  5. Das ist der knifflige Teil. Um die horizontale Größe festzulegen, möchten Sie, dass die Vorder- (rechts) und die Hinterkante (links) der contentView an die Vorder- und Hinterkante self.view anstatt an scrollView angeheftet werden. Obwohl ContenView eine Unteransicht von ScrollView ist, werden die horizontalen Einschränkungen außerhalb des ScrollView-Bereichs liegen und eine Verbindung zu self.view herstellen.

  6. Verbinden Sie alle anderen Ansichtselemente wie gewohnt mit contentView. 

38
NadtheVlad

Wenn Sie einer UIScrollView nur in eine Richtung einen Bildlauf zulassen möchten, müssen Sie die Inhaltsgröße der UIScrollView für die eingeschränkte Dimension mit der Größe des UIScrollView-Frames in derselben Dimension gleichsetzen. In diesem Fall sollte scrollview.contentSize.width gleich scrollview.frame.size.width sein.

Probieren Sie dazu Folgendes aus:

  1. Stellen Sie sicher, dass die Constraints auf die gleiche Weise eingerichtet sind wie in diese Antwort

  2. Fügen Sie Ihrem View-Controller den folgenden Code hinzu:

    override func viewWillLayoutSubviews()
    {
        super.viewWillLayoutSubviews();
        self.scrollView.contentSize.height = 3000; // Or whatever you want it to be.
    }
    

Ich persönlich bin kein Fan von Auto Layout. Wenn Sie daran interessiert sind, dies ohne Auto-Layout zu versuchen - d. Nur mit Code statt mit Einschränkungen - Sie könnten das automatische Layout für die Ansicht des Ansichtscontrollers deaktivieren und Ihre viewWillLayoutSubviews-Methode folgendermaßen ändern:

override func viewWillLayoutSubviews()
{
    super.viewWillLayoutSubviews();

    self.scrollView.frame = self.view.bounds; // Instead of using auto layout
    self.scrollView.contentSize.height = 3000; // Or whatever you want it to be.
}
20
gavdotnet

So mache ich es immer, um mit Einschränkungen vom Storyboard aus vertikal zu scrollen: 

1 Ziehen Sie einen Viewcontroller 

2 Ziehen Sie eine Bildlaufansicht in der Hauptansicht des Controllers mit den Einschränkungen L = 0, T = 0, T = 0 und B = 0 in die Hauptansicht (Controller-Hauptansicht). 

Ziehen Sie ein UIVIew mit der Maus in die Bildlaufansicht, um als Inhaltsansicht mit den Einschränkungen L-0, T = 0, T = 0, B = 0 in die Übersichtsansicht (Scrollansicht) zu gelangen.

  • nun, es ist Zeit für die Einstellung der Inhaltsgröße der Bildlaufansicht, die den Bildlauf horizontal und vertikal wie folgt steuert.

4 - um den horizontalen Bildlauf zu stoppen, stellen Sie die Inhaltsansicht der Bildlaufansicht mit Einschränkung gleich breit ein.

5-machen Höhe der Inhaltsansicht gleich Höhe der Controller-Ansicht. Dies ist temporär , bis wir sie mit scrollbaren Inhalten füllen.

6-add Steuerelemente in der Inhaltsansicht bis zum Ende.

7 - und die wichtigste löschen Sie die Einschränkung, die Sie in Punkt 5 der Höhe der Inhaltsansicht vorgenommen haben, und machen Sie stattdessen eine Einschränkung im Steuerelement unten in der Inhaltsansicht, um eine Ausrichtung nach unten zu haben. Dies hilft beim Erstellen der Inhaltsansicht von der ersten bis zur letzten Kontrolle (alles hängt von diesem Schritt ab). 

8-Run und Ergebnisse sollten wie erwartet sein, ansonsten lass es mich wissen.

Hoffe das hilft!

3
IsPha

Sie können ScrollView normal definieren und die Eigenschaften von ScrollView normal einschränken

        let scrollView = UIScrollView()
    scrollView.translatesAutoresizingMaskIntoConstraints = false
    scrollView.backgroundColor = .white
    self.view.addSubview(scrollView)

    scrollView.leftAnchor.constraint(equalTo: view.leftAnchor, constant: 0.0).isActive = true
    scrollView.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 0.0).isActive = true
    scrollView.rightAnchor.constraint(equalTo: view.rightAnchor, constant: 0.0).isActive = true
    scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: 0.0).isActive = true

Der Trick besteht jedoch darin, wie Sie Ihre Beschriftung (oder eine andere Ansicht) definieren, die möglicherweise breiter als der Bildschirm ist. Anstatt zu benutzen

myLabel.rightAnchor.constraint(equalTo: scrollView.rightAnchor, constant: -10.0).isActive = true

Du solltest benutzen

myLabel.rightAnchor.constraint(equalTo: self.view.rightAnchor, constant: -10.0).isActive = true

Diese zweite Zeile verhindert, dass diese Ansicht ein horizontales Scrollen verursacht. Machen Sie das mit all Ihren Unteransichten und Sie werden nicht horizontal scrollen. (Es wird weiterhin wie geplant vertikal gescrollt.)

Vergessen Sie auch nicht, die unterste Einschränkung für Ihre letzte Unteransicht festzulegen, um sicherzustellen, dass Ihre UIScroll-Ansicht einen vertikalen Bildlauf durchführt.

labelX.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -10.0).isActive = true
1
Vette

Dank @NadtheVlad sah ich endlich das Licht. Einige weitere Fiedelei haben mich gelehrt, dass contentView nur an scrollView's Top, Bottom und Width fixiert werden muss. Keine Notwendigkeit, auf self.view zu verweisen. 

Mit EasyPeasy ist das einfach:

scrollView <- Edges()
contentView <- [Top(), Bottom(), Width().like(scrollView)]
0
jazzgil

Ich verwende diese Implementierung nur für horizontale/vertikale Scrollansichten, obwohl es in Objective-C ist. Ich werde versuchen, die Logik zu erklären, wenn Ihnen etwas unklar ist. 

//Getting iDevice's screen width
CGRect screenRect = [[UIScreen mainScreen] bounds];
CGFloat screenWidth = screenRect.size.width;

//Setting the right content size - only height is being calculated depenging on content.
CGSize contentSize = CGSizeMake(screenWidth, HEIGHT_OF_YOUR_CONTENT);
self.scrollView.contentSize = contentSize;

Jetzt wird die Breite der contentSize-Eigenschaft der Bildlaufansicht an die tatsächliche Breite des Bildschirms des Geräts angehängt, sodass die Bildlaufansicht nur in vertikaler Richtung gescrollt wird.

0
Richard Topchiy