Wyłączanie przewijania w pionie w UIScrollView


Odpowiedzi:


121

Spróbuj ustawić wysokość contentSize na wysokość scrollView. Następnie należy wyłączyć przewijanie w pionie, ponieważ nie byłoby nic do przewijania w pionie.

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

Właśnie zaoszczędziłeś mi dużo czasu na debugowaniu tego dziwnego problemu. Dzięki!
jpm

2
@fabb skąd wiadomo, że ramka została zmieniona?
Sam

137

od iOS7:

po pierwsze: szerokość rozmiaru treści musi być równa szerokości widoku przewijania

po drugie: w twoim initWithNibName:

self.automaticallyAdjustsScrollViewInsets = NO;

Otóż ​​to.


Cudowne rozwiązanie. Działał jak urok. Czy wpłynie to na rozmiar pozostałych widoków w moim ViewController? (Przyciski, etykiety ...) Mam na myśli, że „self” jest kontrolerem UIViewController w moim przypadku
voghDev

@voghDev no, nie ma to żadnego wpływu na podglądy w widoku przewijania.
Mirko Brunner

Amazing dodał to do metody viewdidload na moich kontrolerach widoku, które miały problemy.
StackRunner,

jeśli używasz navigationController, a Twój widok scrollview znajduje się za tytułem navigationBar, takim jak mój, użyj metody viewDidLoad. To rozwiązuje.
EFE,

1
Możesz osiągnąć to samo bezpośrednio w ustawieniach scenorysu, bez żadnej linii kodu. Po prostu wybierz kontroler przewijania widoku i odznacz pole „Dopasuj wstawki widoku przewijania” w inspektorze atrybutów.
Morpheus78

49

tak, odpowiedź pt2ph8 jest prawidłowa,

ale jeśli z jakiegoś dziwnego powodu rozmiar contentSize powinien być wyższy niż UIScrollView, możesz wyłączyć przewijanie w pionie implementując metodę protokołu UIScrollView

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

po prostu dodaj to do swojego UIViewController

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)];
}

jest to po prostu metoda wywoływana, gdy użytkownik przewija twój UIScrollView, i robiąc to, wymuszasz, aby jego zawartość była zawsze taka sama .y


6
Bóg! Proszę NIE deklarować starej zmiennej w pliku .m, jak float oldY;w powyższym kodzie. To jest symbol zmiennej w stylu C dla każdej aplikacji, zmienna MUSI być zadeklarowana jako element instancji klasy kontrolera.
Itachi

21

Uwzględnij następującą metodę

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

i ustaw szerokość rozmiaru zawartości widoku przewijania równą szerokości widoku przewijania.


1
Można to również zrobić w Storyboard, wybierając kontroler widoku i odznaczając tam właściwość
justColbs

1
Nie podoba mi się to, ponieważ ustawia to dla wszystkich widoków przewijania ... Żałuję, że nie możesz być specyficzny dla jednego widoku przewijania na schemacie bez tworzenia nowej klasy
ScrollView

20

Musisz przekazać 0 w rozmiarze zawartości, aby wyłączyć w wybranym kierunku.

Wyłączanie przewijania w pionie

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

Wyłączanie przewijania w poziomie

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

1
Spowoduje to ustawienie contentSize widoku na 0 na ustawionej osi. ContentSize odnosi się do rozmiaru treści, więc chcemy przekazać wysokość ekranu, aby wyłączyć przewijanie w pionie poza tę ramkę. rozwiązanie oznaczone jako prawidłowe jest prawidłowe.
system

To działało dobrze dla mnie. ustawienie wysokości jako zawartości Wysokość rozmiaru nadal powoduje przewijanie w pionie.
KoreanXcodeWorker

1
To nie zadziałało dla mnie. Próbowałem też self.automaticallyAdjustsScrollViewInsets
StackRunner

To jest to! Ustawienie wysokości widoku przewijania nie działało dla mnie, ale tak
Echizzle

18

Zaktualizowałem rozmiar treści, aby wyłączyć przewijanie w pionie, a możliwość przewijania nadal pozostała. Potem doszedłem do wniosku, że muszę również wyłączyć odbijanie w pionie, aby całkowicie wyłączyć przewijanie.

Może są też ludzie z tym problemem.


Uratowałeś mnie. Moje treści Rozmiar i kadr były takie same i przez całe życie nie mogłem dowiedzieć się, co jest nie tak. Wielkie dzięki!!
yuf

2
Twoja odpowiedź brzmi: dlaczego kocham stackoverflow! :-) Święty dymie ... to doprowadziło mnie do szału! Masz rację. To efekt odbicia. Chcę mieć efekt odbijania, ale nie wtedy, gdy nie ma potrzeby przewijania, więc będę teraz starał się wyłączyć / ponownie włączyć ten efekt w kodzie, w zależności od tego, czy istnieje potrzeba przewijania.
Erik van der Neut

2
Okay, bardzo łatwo włączać / wyłączać odbicia na UIScrollView w czasie wykonywania. W moim przypadku zależy mi tylko na wysokości zawartości przewijania i to załatwiło sprawę: 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)];

}

musisz to potwierdzić UIScrollViewDelegate

aScrollView.delegate = self;

4

Po prostu ustaw y, aby zawsze był na wierzchu. Należy zachować zgodność z UIScrollViewDelegate

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

Pozwoli to zachować efekt spowolnienia / przyspieszenia przewijania.


4

W systemie iOS 11 pamiętaj, aby dodać następujące informacje, jeśli chcesz utworzyć widok przewijania, który przylega do granic ekranu, a nie do bezpiecznego obszaru:

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

1
w sumie. dziękuję panu tysiąc razy! uratowałeś mi dzień
ha100

0

Z iOS11 można skorzystać z następującej własności

let frameLayoutGuide: UILayoutGuide

Jeśli ustawisz ograniczenia dla frameLayoutGuide.topAnchor i frameLayoutGuide.bottomAnchor tych samych kotwic jakiś podrzędny swojego Scrollview następnie przewijania pionowego będzie wyłączona, a wysokość Scrollview będzie równa wysokości jego podrzędny.


0

Najbardziej oczywistym rozwiązaniem jest zakaz zmian współrzędnych y w Twojej podklasie.

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

To jedyne odpowiednie rozwiązanie w sytuacjach, gdy:

  1. Nie możesz lub po prostu nie chcesz używać pełnomocnika.
  2. Wysokość Twojej zawartości jest większa niż wysokość kontenera

0

Wiele odpowiedzi obejmuje ustawienie wartości contentOffset0. Miałem przypadek, w którym chciałem, aby widok wewnątrz scrollView był wyśrodkowany. To wykonało pracę za mnie:

public func scrollViewDidScroll(_ scrollView: UIScrollView) {
    scrollView.contentOffset.y = -scrollView.contentInset.top
}
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.