Uwaga: udzielona tutaj odpowiedź nie działa dla mnie.
Mam UIScrollView (nie widok tabeli, tylko niestandardową rzecz), a gdy użytkownik wykonuje określone czynności, chcę zabić przewijanie (przeciąganie lub zwalnianie) w widoku. Próbowałem zrobić np. Tak:
[scrollView scrollRectToVisible:CGRectInset([scrollView bounds], 10, 10) animated:NO];
na teorii, że biorąc pod uwagę prostokąt, który jest już widoczny, przewijanie zatrzyma się tam, gdzie jest, ale okazuje się, że nie ma to żadnego efektu - najwyraźniej widok przewijania widzi, że dany prostokąt jest w granicach i przyjmuje bez akcji. I można dostać zwój do przystanku, jeśli daję rect, która jest zdecydowanie poza aktualnie niewidzialnych granic, ale wewnątrz contentSize widoku. Wydaje się, że zgodnie z oczekiwaniami powoduje to zatrzymanie widoku ... ale także przeskakuje w inne miejsce. Prawdopodobnie mógłbym trochę bawić się na marginesach, aby to zadziałało w miarę OK, ale czy ktoś zna czysty sposób na zatrzymanie widoku przewijania, który robi swoje?
Dzięki.
źródło
setContentOffset
wystarczy jedno wywołanie . Widok przewijania automatycznie zaokrągla przesunięcie zawartości.Ogólna odpowiedź brzmi:
[scrollView setContentOffset:offset animated:NO]
to nie to samo, co[scrollView setContentOffset:offset]
![scrollView setContentOffset:offset animated:NO]
faktycznie zatrzymuje każdą uruchomioną animację.[scrollView setContentOffset:offset]
nie zatrzymuje żadnej uruchomionej animacji.scrollView.contentOffset = offset
: nie zatrzymuje żadnej uruchomionej animacji.Nie jest to nigdzie udokumentowane, ale jest to zachowanie przetestowane na iOS 6.1 i iOS 7.1 - prawdopodobnie również wcześniej.
Zatem rozwiązanie zatrzymania uruchomionej animacji / spowolnienia jest proste:
[scrollView setContentOffset:scrollView.contentOffset animated:NO];
Zasadniczo to, co powiedział David Liu w swojej zredagowanej odpowiedzi. Ale chciałem wyjaśnić, że te dwa API NIE są takie same.
Swift 3:
scrollView.setContentOffset(scrollView.contentOffset, animated:false)
źródło
Dla mnie zaakceptowana powyżej odpowiedź Davida Lui nie zadziałała. Oto, co ostatecznie zrobiłem:
- (void)killScroll { self.scrollView.scrollEnabled = NO; self.scrollView.scrollEnabled = YES; }
Na ile to jest warte, używam iPhone Simulator iOS 6.0.
źródło
supportedInterfaceOrientations
aby zapobiec kontynuowaniu zdarzeń przewijania, jeśli użytkownik obraca urządzenie podczas przewijania , co czasami jest bałaganem w zależności od tego, co robisz.Oto, co robię dla moich widoków przewijania i wszystkich innych powiązanych podklas:
- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset { *targetContentOffset = scrollView.contentOffset; }
Ustawia to
targetContentOffset
nascrollView
bieżące przesunięcie, powodując zatrzymanie przewijania, ponieważ osiągnęło cel. W rzeczywistości sensowne jest użycie metody, której celem jest ustalenie celu przez użytkownikówcontentOffset
.Szybki
func scrollViewWillEndDragging(_ scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer<CGPoint>) { targetContentOffset.pointee = scrollView.contentOffset }
źródło
Zatrzymać przewijać SWIFT :
scrollView.setContentOffset(scrollView.contentOffset, animated: false)
źródło
Właściwie… Najbardziej „nowoczesny” sposób byłby ->
scrollview.panGestureRecognizer.enabled = false; scrollview.panGestureRecognizer.enabled = true;
To dezaktywuje rozpoznawanie gestów, który jest odpowiedzialny za przewijanie tylko na chwilę, co zabija bieżący dotyk. Użytkownik musiałby podnieść palec i odłożyć go z powrotem, aby ponownie rozpocząć przewijanie.
Edycja: To faktycznie po prostu zabija bieżące przeciąganie użytkownika, ale nie zatrzymuje natychmiast zwalniania, jeśli widok przewijania jest obecnie w tym stanie. Aby to zrobić, poprawna edycja zaakceptowanych odpowiedzi jest w zasadzie najlepszym sposobem xD
[scrollview setContentOffset: scrollview.contentOffset animated:false];
źródło
Najczystszym sposobem będzie podklasa UIScrollView i dostarczenie własnej metody setContentOffset. Powinno to przekazać komunikat, tylko jeśli nie włączyłeś swojej
freeze
właściwości boolowskiej.Tak jak to:
BOOL freeze; // and the @property, @synthesize lines.. -(void)setContentOffset:(CGPoint)offset { if ( !freeze ) [super setContentOffset:offset]; }
Następnie, aby zamrozić:
scrollView.freeze = YES;
źródło
decelerationRate = 1e10;
podczas zatrzymania == TAK?Ta odpowiedź zadziałała dla mnie: Deactivate UIScrollView decelerating
-(void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView{ [scrollView setContentOffset:scrollView.contentOffset animated:YES]; }
źródło
Wyłącz tylko przewijanie interakcji użytkownika. (szybki)
scrollView.isScrollEnabled = false
Wyłącz podczas animacji przewijania po przeciągnięciu. (szybki)
var scrollingByVelocity = false func scrollViewWillBeginDecelerating(_ scrollView: UIScrollView) { if !scrollingByVelocity { scrollView.setContentOffset(scrollView.contentOffset, animated: false) } }
źródło
Wypróbowałem te metody w widoku kolekcji:
self.collectionView.collectionViewLayout.finalizeCollectionViewUpdates()
źródło
To działa dla mnie w Swift 4.2 :
func killScroll() { self.scrollView.isScrollEnabled = false; self.scrollView.isScrollEnabled = true; }
... jako rozszerzenie:
extension UIScrollView { func killScroll() { self.isScrollEnabled = false; self.isScrollEnabled = true; } }
źródło
Chciałem wyłączyć przewijanie tylko wtedy, gdy określony UIView w widoku przewijania jest źródłem dotyku podczas przesuwania. Przeniesienie UIView poza UIScrollView wymagałoby sporo refaktoryzacji, ponieważ mieliśmy złożoną hierarchię widoków.
Aby obejść ten problem, dodałem pojedynczy UIPanGestureRecognizer do widoku podrzędnego, w którym chciałem zapobiec przewijaniu. Ten UIPanGestureRecognizer będzie
cancelsTouchesInView
zapobiega aktywacji panGesture UIScrollView.To trochę `` hack '', ale jest to bardzo łatwa zmiana, a jeśli używasz XIB lub Storyboard, wszystko, co musisz zrobić, to przeciągnąć gest panoramowania na dany podwidok.
źródło
SWift 5+
za pomocą rozszerzenia
extension UIScrollView { func stopDecelerating() { let contentOffset = self.contentOffset self.setContentOffset(contentOffset, animated: false) } }
posługiwać się
myScrollView.stopDecelerating() // your stuff
źródło