Mam UIScrollView
dozwolone tylko przewijanie w poziomie i chciałbym wiedzieć, w którym kierunku (w lewo, w prawo) użytkownik przewija. To, co zrobiłem, było podklasowanie UIScrollView
i zastąpienie touchesMoved
metody:
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event
{
[super touchesMoved:touches withEvent:event];
UITouch *touch = [touches anyObject];
float now = [touch locationInView:self].x;
float before = [touch previousLocationInView:self].x;
NSLog(@"%f %f", before, now);
if (now > before){
right = NO;
NSLog(@"LEFT");
}
else{
right = YES;
NSLog(@"RIGHT");
}
}
Ale ta metoda czasami nie jest wywoływana, kiedy się przeprowadzam. Co myślisz?
iphone
ios
cocoa-touch
uiscrollview
Alex1987
źródło
źródło
Odpowiedzi:
Określenie kierunku jest dość proste, ale należy pamiętać, że kierunek może się zmieniać kilka razy w trakcie gestu. Na przykład, jeśli masz widok przewijania z włączonym stronicowaniem, a użytkownik przesuwa palcem, aby przejść do następnej strony, początkowy kierunek może być prawy, ale jeśli masz włączone odbijanie, na krótko nie będzie w żadnym kierunku i potem na krótko idź w lewo.
Aby określić kierunek, musisz użyć
UIScrollView scrollViewDidScroll
delegata. W tym przykładzie utworzyłem zmienną o nazwie,lastContentOffset
której używam do porównania bieżącego przesunięcia zawartości z poprzednim. Jeśli jest większy, scrollView przewija w prawo. Jeśli jest mniej, scrollView przewija się w lewo:Używam następującego wyliczenia do zdefiniowania kierunku. Ustawienie pierwszej wartości na ScrollDirectionNone ma tę dodatkową zaletę, że ustawia ten kierunek jako domyślny podczas inicjowania zmiennych:
źródło
lastContentOffset = scrollView.contentOffset.x;
lastContentOffset
typ. Jeśli chodzi o właściwość vs zmienne statyczne: każde rozwiązanie jest dobrym wyborem. Nie mam żadnych preferencji. To dobra uwaga.W takim przypadku w systemie iOS 5 i nowszym użyj przycisku,
UIScrollViewDelegate
aby określić kierunek gestu panoramy użytkownika:źródło
Używanie
scrollViewDidScroll:
to dobry sposób na znalezienie bieżącego kierunku.Jeśli chcesz poznać kierunek po zakończeniu przewijania, użyj następujących poleceń:
źródło
Nie trzeba dodawać dodatkowej zmiennej, aby to śledzić. Wystarczy użyć
UIScrollView
„spanGestureRecognizer
własności takiego. Niestety działa to tylko wtedy, gdy prędkość nie wynosi 0:Możesz użyć kombinacji składników x i y do wykrywania w górę, w dół, w lewo i w prawo.
źródło
Rozwiązanie
źródło
velocityInView
zamiasttranslationInView
. To rozwiązuje problem pojawiający się przy zmianie kierunku w tym samym ruchu.Swift 4:
Aby przewijać w poziomie, możesz po prostu zrobić:
Aby przewijać w pionie, zmień za
.x
pomocą.y
źródło
W iOS8 Swift zastosowałem tę metodę:
Mam widok dynamiczny, który zmienia lokalizacje podczas przewijania przez użytkownika, dzięki czemu widok może wyglądać, jakby pozostał w tym samym miejscu na ekranie. Śledzę również, kiedy użytkownik idzie w górę lub w dół.
Oto także alternatywny sposób:
źródło
crollViewDidEndDecelerating
prawda?Oto, co zadziałało dla mnie (w Objective-C):
źródło
źródło
Alternatywnie można obserwować kluczową ścieżkę „contentOffset”. Jest to przydatne, gdy nie można ustawić / zmienić delegata widoku przewijania.
Po dodaniu obserwatora możesz teraz:
Pamiętaj, aby w razie potrzeby usunąć obserwatora. np. możesz dodać obserwatora do widokuWillAppear i usunąć go w viewWillDisappear
źródło
W krótkim:
Możesz to zrobić również w scrollViewDidScroll.
źródło
Oto moje rozwiązanie dla zachowania jak w odpowiedzi @followben, ale bez strat z powolnym startem (gdy dy wynosi 0)
źródło
Sprawdziłem niektóre odpowiedzi i opracowałem odpowiedź AnswerBot, pakując wszystko w kropkę w kategorii UIScrollView. Zamiast tego „lastContentOffset” jest zapisywany w widoku uiscrollview, a następnie wystarczy wywołać:
Kod źródłowy na https://github.com/tehjord/UIScrollViewScrollingDirection
źródło
Wolę filtrować na podstawie odpowiedzi @ memmons
W celu C:
Podczas testowania w
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
:self.lastContentOffset
zmienia się bardzo szybko, różnica wartości wynosi prawie 0,5f.To nie jest konieczne.
A czasami, gdy jest obsługiwany w dokładnym stanie, twoja orientacja może się zgubić. (instrukcje implementacji czasami pomijane)
Jak na przykład :
W Swift 4:
źródło
Gdy stronicowanie jest włączone, możesz użyć tego kodu.
źródło
Wydaje mi się, że kody same się wyjaśniają. CGFloat różnica1 i różnica2 zadeklarowane w prywatnym interfejsie tej samej klasy. Dobrze, jeśli contentSize pozostaje taki sam.
źródło
Ok, więc dla mnie ta implementacja działa naprawdę dobrze:
Spowoduje to uruchomienie textView do odrzucenia po zakończeniu przeciągania
źródło
Skorzystaj z tej metody widoku przewijania.
Jeżeli współrzędna prędkości wynosi + ve, widok przewijania przewija w dół, a jeśli jest -ve, przewijanie przewija w górę. Podobnie przewijanie w lewo i w prawo można wykryć za pomocą współrzędnej x.
źródło
Krótko i łatwo byłoby, po prostu sprawdź wartość prędkości, jeśli jest większa od zera, to przewijanie w lewo, gdzie indziej:
źródło
Jeśli pracujesz z UIScrollView i UIPageControl, ta metoda zmieni również widok strony PageControl.
Dzięki kod Swift @Esq.
źródło
Swift 2.2 Proste rozwiązanie, które śledzi jeden i wiele kierunków bez żadnych strat.
źródło
We wszystkich górnych odpowiedziach dwoma głównymi sposobami rozwiązania problemu jest użycie
panGestureRecognizer
lubcontentOffset
. Obie metody mają swoje wady i zalety.Metoda 1: panGestureRecognizer
Kiedy używasz
panGestureRecognizer
tego, co sugerował @followben, jeśli nie chcesz programowo przewijać widoku przewijania, działa poprawnie.Cons
Ale jeśli przeniesiesz widok przewijania z następującym kodem, górny kod nie może go rozpoznać:
Metoda 2: contentOffset
Cons
Jeśli chcesz programowo zmienić zawartość Offset, podczas przewijania (np. Gdy chcesz utworzyć przewijanie nieskończone), ta metoda stanowi problem, ponieważ możesz zmienić
contentOffset
podczas zmiany miejsc widoków treści i tym razem przeskoczyć górny kod, przewijając w prawo lub lewo.źródło
Odpowiedź od Mos6y https://medium.com/@Mos6yCanSwift/swift-ios-determine-scroll-direction-d48a2327a004
źródło