Mam UIView
podobny do iPhone'a Springboard. Stworzyłem go za pomocą UIScrollView
i UIButtons
. Chcę wyłączyć przewijanie w poziomie we wspomnianym widoku przewijania. Chcę tylko przewijania w pionie. Jak to osiągnąć?
ios
objective-c
uiscrollview
Rahul Vyas
źródło
źródło
Odpowiedzi:
Musisz ustawić
contentSize
właściwośćUIScrollView
. Na przykład, jeśli twójUIScrollView
ma 320 pikseli szerokości (szerokość ekranu), możesz to zrobić:CGSize scrollableSize = CGSizeMake(320, myScrollableHeight); [myScrollView setContentSize:scrollableSize];
UIScrollView
Wtedy tylko przewijać w pionie, ponieważ może już wyświetlać wszystko poziomo.źródło
AKTUALIZACJA: (po tym, jak @EranMarom wskazał w swoim komentarzu)
Możesz zatrzymać przewijanie w poziomie lub w pionie w
ScrollViewDelegate
metodzie. Oto jak,Zatrzymuje przewijanie w poziomie:
Jeśli chcesz przewijać w poziomie, musisz zwiększyć contentOffset.x. Zapobieganie, które zatrzymuje przewijanie widoku w poziomie.
- (void)scrollViewDidScroll:(UIScrollView *)sender { sender.contentOffset.x = 0.0 }
Zatrzymuje przewijanie w pionie:
Jeśli chcesz przewijać w pionie, musisz zwiększyć contentOffset.y. Zapobieganie, które zatrzymuje przewijanie widoku w pionie.
- (void)scrollViewDidScroll:(UIScrollView *)sender { sender.contentOffset.y = 0.0 }
Powyższy kod uniemożliwia zmiany w
x
iy
tematycescrollview contentOffset
, a to prowadzi do zatrzymania przewijania wscrollViewDidScroll:
metodzie.źródło
scrollView.contentOffset = CGPointMake(0, scrollView.contentOffset.y);
aby wyłączyć przewijanie w poziomie. Uważam, że jest bardziej czytelny, jest mniejszy i nie ma sensu robić testu dla zera, ponieważ praktycznie nie ma narzutu z kodem, który uruchamia się tak rzadko (tj. Maksymalnie kilkadziesiąt razy na sekundę).scrollView.contentOffset.y = 0.0
aby zatrzymać przewijanie w pionie iscrollView.contentOffset.x = 0.0
zatrzymać przewijanie w poziomie wscrollViewDidScroll()
funkcji delegata. Uważam jednak, że upewnienie się, żescrollView.contentSize
równa sięscrollView.frame.size
to jest lepszym (poprawnym) rozwiązaniem. Zobacz odpowiedź @danbeaulieu.od czasu użycia iOS7
self.automaticallyAdjustsScrollViewInsets = NO;
// i utwórz scroller strony z 3 stronami
self.pageView = [[UIScrollView alloc] initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)]; [self.pageView setContentSize:CGSizeMake(self.view.frame.size.width*3, self.view.frame.size.height)]; [self.pageView setShowsVerticalScrollIndicator:NO]; [self.pageView setPagingEnabled:YES]; [self.view addSubview:self.pageView];
źródło
self.collectionView.pagingEnabled = YES;
pomogło mi rozwiązać problem z płynnym przewijaniem (bez przeciągania). ProblemscrollViewWillEndDragging:
tkwił w metodzie - targetContentOffset był taki sam jak scrollView.contentOffset i logika wykrywania stron nie działa poprawnie.Utwórz dwa wyloty, jeden do widoku i jeden do widoku przewijania:
@IBOutlet weak var myView: UIView! @IBOutlet weak var scrollView: UIScrollView!
Następnie w swoim viewDidLayoutSubviews możesz dodać następujący kod:
let scrollSize = CGSize(width: myView.frame.size.width, height: myView.frame.size.height) scrollView.contentSize = scrollSize
To, co zrobiliśmy, to zebranie wysokości i szerokości widoku i ustawienie rozmiaru zawartości scrollViews, aby pasował do niego. Spowoduje to zatrzymanie przewijania widoku przewijania w poziomie.
Więcej myśli:
CGSizeMake pobiera szerokość i wysokość za pomocą CGFloats. Może być konieczne użycie istniejącej wysokości UIScrollViews dla drugiego parametru. Który wyglądałby tak:
let scrollSize = CGSize(width: myView.frame.size.width, height: scrollView.contentSize.height)
źródło
W moim przypadku z Swift 4.2 możesz użyć:
Wyłącz przewijanie w pionie:
func scrollViewDidScroll(_ scrollView: UIScrollView) { scrollView.contentOffset.y = 0.0 }
Wyłącz przewijanie w poziomie:
func scrollViewDidScroll(_ scrollView: UIScrollView) { scrollView.contentOffset.x = 0.0 }
źródło
Możesz wybrać widok, a następnie
Attributes Inspector
odznaczyćUser Interaction Enabled
.źródło
W moim przypadku szerokość contentView była większa niż szerokość UIScrollView i to było przyczyną niechcianego przewijania w poziomie. Rozwiązałem to, ustawiając szerokość contentView równą szerokości UIScrollView.
Mam nadzieję, że to komuś pomoże
źródło
Miałem ustawioną zawartość tableview w viewDidLoad (jak poniżej), która powoduje przewijanie w poziomie
self.tableView.contentInset = UIEdgeInsetsMake(0, 30, 0, 0);
Sprawdź, czy z różnych powodów ustawiono zestaw contentview widoku tabeli i wyłącz go
źródło
Zmagałem się z tym przez jakiś czas próbując bezskutecznie różnych sugestii w tym i innych wątkach.
Jednak w innym wątku (nie jestem pewien, gdzie) ktoś zasugerował, że użycie negatywnego ograniczenia na UIScrollView zadziałało dla niego.
Wypróbowałem więc różne kombinacje ograniczeń z niespójnymi wynikami. Ostatecznie zadziałało dla mnie dodanie wiodących i końcowych ograniczeń -32 do widoku przewijania i dodanie (niewidocznego) widoku tekstowego o szerokości 320 (i wyśrodkowany).
źródło
Spróbuj tego:
CGSize scrollSize = CGSizeMake([UIScreen mainScreen].bounds.size.width, scrollHeight); [scrollView setContentSize: scrollSize];
źródło
Wyłącz przewijanie w poziomie, zastępując
contentOffset
właściwość w podklasie.override var contentOffset: CGPoint { get { return super.contentOffset } set { super.contentOffset = CGPoint(x: 0, y: newValue.y) } }
źródło
Wprowadzona w iOS 11 to nowa właściwość w
UIScrollView
var contentLayoutGuide: UILayoutGuide
Dokumentacja stwierdza, że:
Wraz z innymi ograniczeniami autoLayout które można dodawać będziemy chcieli, aby powiązać
widthAnchor
zUIScrollView
„scontentLayoutGuide
być tej samej wielkości jako«ramy». Możesz użyćframeLayoutGuide
(również wprowadzonej w iOS 11) lub dowolnej szerokości zewnętrznej (takiej jak TwojasuperView
).przykład:
NSLayoutConstraint.activate([ scrollView.contentLayoutGuide.widthAnchor.constraint(equalTo: self.widthAnchor) ])
Dokumentacja: https://developer.apple.com/documentation/uikit/uiscrollview/2865870-contentlayoutguide
źródło
Kiedy już to zrobiłem, zastępując UIScrollView UITableView z tylko 1 komórką, działało dobrze.
źródło
Użyj tej pojedynczej linii.
self.automaticallyAdjustsScrollViewInsets = NO;
źródło