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);
pt2ph8
źródło
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.

Mirko Brunner
źródło
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

meronix
źródło
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.

Febin P
źródło
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);
Mani
źródło
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.

bolonn
źródło
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;

źródło
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.

manuelsantos
źródło
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];
}
Michał
źródło
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.

malex
źródło
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
iWheelBuy
źródło
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
}
regina_fallangi
źródło