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);
pt2ph8
quelle
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.

Mirko Brunner
quelle
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

Meronix
quelle
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.

Febin P.
quelle
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);
Mani
quelle
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.

Bolonn
quelle
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;

quelle
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.

manuelsantos
quelle
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];
}
Michael
quelle
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.

Malex
quelle
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
iWheelBuy
quelle
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
}
regina_fallangi
quelle