Deaktivieren des vertikalen Bildlaufs in UIScrollView


Antworten:


121

Versuchen Sie, die Höhe von contentSize auf die Höhe von scrollView einzustellen. Dann sollte der vertikale Bildlauf deaktiviert werden, da nichts zum vertikalen Bildlauf vorhanden wäre.

scrollView.contentSize = CGSizeMake(scrollView.contentSize.width,scrollView.frame.size.height);

Sie haben mir gerade viel Zeit beim Debuggen dieses seltsamen Problems gespart. Vielen Dank!
jpm

2
@fabb woher weiß man wann der Frame geändert wird?
Sam

137

seit iOS7:

Erstens: Die Breite der Inhaltsgröße muss der Breite Ihrer Bildlaufansicht entsprechen

zweitens: in Ihrem initWithNibName:

self.automaticallyAdjustsScrollViewInsets = NO;

Das ist es.


Wunderbare Lösung. Lief wie am Schnürchen. Beeinflusst es die Größe der restlichen Ansichten in meinem ViewController? (Buttons, Labels ..) Ich meine, "self" ist in meinem Fall ein UIViewController
voghDev

@voghDev nein, es hat keine Auswirkungen auf die Unteransichten in Ihrer Bildlaufansicht.
Mirko Brunner

Amazing fügte dies der viewdidload-Methode auf meinen View-Controllern hinzu, bei denen Probleme auftraten.
StackRunner

Wenn Sie navigationController verwenden und sich Ihre Bildlaufansicht hinter dem Titel der Navigationsleiste befindet, wie meine, verwenden Sie sie unter der viewDidLoad-Methode. Es löst.
EFE

1
Sie können dasselbe direkt in den Storyboard-Einstellungen ohne Codezeile erreichen. Wählen Sie einfach den Controller für die Bildlaufansicht aus und deaktivieren Sie im Attributinspektor die Option "Bildlaufansichten anpassen".
Morpheus78

49

Ja, die Antwort von pt2ph8 ist richtig.

Sollte Ihre contentSize jedoch aus irgendeinem seltsamen Grund höher als die UIScrollView sein, können Sie das vertikale Scrollen deaktivieren, indem Sie die UIScrollView-Protokollmethode implementieren

 -(void)scrollViewDidScroll:(UIScrollView *)aScrollView;

Fügen Sie dies einfach in Ihren UIViewController ein

float oldY; // here or better in .h interface

- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
    [aScrollView setContentOffset: CGPointMake(aScrollView.contentOffset.x, oldY)];
    // or if you are sure you wanna it always on top:
    // [aScrollView setContentOffset: CGPointMake(aScrollView.contentOffset.x, 0)];
}

Dies ist nur die Methode, die aufgerufen wird, wenn der Benutzer durch Ihre UIScrollView scrollt und dabei erzwingt, dass der Inhalt immer dieselbe .y hat


6
Gott! Bitte deklarieren Sie die oldY-Variable NICHT in der .m-Datei, wie float oldY;im obigen Code beschrieben. Dies ist ein Variablensymbol im C-Stil. Pro Anwendung MUSS die Variable als Instanzmitglied der Controller-Klasse deklariert werden.
Itachi

21

Schließen Sie die folgende Methode ein

-(void)viewDidLayoutSubviews{
    self.automaticallyAdjustsScrollViewInsets = NO;
}

und stellen Sie die Breite der Inhaltsgröße der Bildlaufansicht gleich der Breite der Bildlaufansicht ein.


1
Dies kann auch in Storyboard erfolgen, indem Sie den View Controller auswählen und die Eigenschaft dort
deaktivieren

1
Ich mag das nicht, weil es es für alle Bildlaufansichten
festlegt

20

Sie müssen 0 in der Inhaltsgröße übergeben, um zu deaktivieren, in welche Richtung Sie möchten.

Deaktivieren des vertikalen Bildlaufs

scrollView.contentSize = CGSizeMake(scrollView.contentSize.width,0);

Deaktivieren des horizontalen Bildlaufs

scrollView.contentSize = CGSizeMake(0,scrollView.contentSize.height);

1
Dadurch wird die Inhaltsgröße der Ansicht auf der von Ihnen festgelegten Achse auf 0 gesetzt. ContentSize bezieht sich auf die Größe des Inhalts. Daher möchten wir die Höhe des Bildschirms übergeben, um das vertikale Scrollen über diesen Frame hinaus zu deaktivieren. Die als korrekt gekennzeichnete Lösung ist korrekt.
System

Das hat bei mir gut funktioniert. Wenn ich die Höhe als contentSize-Höhe einstelle, kann ich immer noch vertikal scrollen.
KoreanXcodeWorker

1
Das hat bei mir nicht funktioniert. Auch versucht self.automaticallyAdjustsScrollViewInsets
StackRunner

Das ist es! Das Einstellen auf die Höhe der Bildlaufansicht hat bei mir nicht funktioniert, aber das hat funktioniert
Echizzle

18

Ich habe die Inhaltsgröße aktualisiert, um das vertikale Scrollen zu deaktivieren, und die Fähigkeit zum Scrollen blieb weiterhin erhalten. Dann stellte ich fest, dass ich auch den vertikalen Sprung deaktivieren musste, um den Bildlauf vollständig zu deaktivieren.

Vielleicht gibt es auch Leute mit diesem Problem.


Du hast mich gerettet. Meine Inhaltsgröße und mein Rahmen waren gleich und ich konnte für mein ganzes Leben nicht herausfinden, was los war. Vielen Dank!!
Yuf

2
Ihre Antwort ist, warum ich Stackoverflow liebe! :-) Heiliger Rauch ... das hat mich verrückt gemacht! Du hast recht. Es ist der Bounce-Effekt. Ich möchte den Bounce-Effekt, aber nicht, wenn kein Bildlauf erforderlich ist. Daher werde ich versuchen, diesen Effekt jetzt im Code zu deaktivieren / wieder zu aktivieren, je nachdem, ob ein Bildlauf erforderlich ist.
Erik van der Neut

2
Okay, es ist sehr einfach, die Bounces in einer UIScrollView zur Laufzeit zu aktivieren / deaktivieren. In meinem Fall ist mir nur die Höhe des Bildlaufinhalts wichtig, und dies hat den Trick gemacht: self.scrollView.bounces = (BOOL) (self.scrollView.contentSize.height> self.scrollView.frame.size.height);
Erik van der Neut

12
- (void)scrollViewDidScroll:(UIScrollView *)aScrollView
{
    [aScrollView setContentOffset: CGPointMake(aScrollView.contentOffset.x,0)];

}

Sie müssen bestätigt haben UIScrollViewDelegate

aScrollView.delegate = self;

4

Stellen Sie einfach das y so ein, dass es immer oben ist. Muss mit UIScrollViewDelegate übereinstimmen

func scrollViewDidScroll(scrollView: UIScrollView) {
        scrollView.contentOffset.y = 0.0
}

Dadurch bleibt der Verzögerungs- / Beschleunigungseffekt des Bildlaufs erhalten.


4

Denken Sie unter iOS 11 daran, Folgendes hinzuzufügen, wenn Sie eine Bildlaufansicht erstellen möchten, die sich an die Bildschirmgrenzen und nicht an einen sicheren Bereich hält:

if (@available(iOS 11.0, *)) {
    [self.scrollView setContentInsetAdjustmentBehavior:UIScrollViewContentInsetAdjustmentNever];
}

1
Nach alldem. Vielen Dank, Sir! Du hast meinen Tag gerettet
ha100

0

Ab iOS11 kann man die folgende Eigenschaft verwenden

let frameLayoutGuide: UILayoutGuide

Wenn Sie Einschränkungen für frameLayoutGuide.topAnchor und frameLayoutGuide.bottomAnchor auf dieselben Anker in einer Unteransicht Ihrer scrollView festlegen, wird der vertikale Bildlauf deaktiviert und die Höhe der scrollView entspricht der Höhe der Unteransicht.


0

Die naheliegendste Lösung besteht darin, Änderungen der y-Koordinate in Ihrer Unterklasse zu verbieten.

override var contentOffset: CGPoint {
  get {
    return super.contentOffset
  }
  set {
    super.contentOffset = CGPoint(x: newValue.x, y: 0)
  }
}

Dies ist die einzig geeignete Lösung in Situationen, in denen:

  1. Sie dürfen keinen Delegaten verwenden oder möchten ihn einfach nicht verwenden.
  2. Ihre Inhaltshöhe ist größer als die Containerhöhe

0

Viele Antworten beinhalten das Setzen contentOffsetvon 0. Ich hatte einen Fall, in dem ich wollte, dass die Ansicht in der scrollView zentriert wird. Das hat den Job für mich gemacht:

public func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.y = -scrollView.contentInset.top
}
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.