UIScrollViewDelegate ma dwie metody delegata scrollViewDidScroll:
a scrollViewDidEndScrollingAnimation:
jednak żadna z nich nie powiedzieć podczas przewijania została zakończona. scrollViewDidScroll
informuje tylko o tym, że widok przewijania został przewinięty, a nie o zakończeniu przewijania.
Druga metoda scrollViewDidEndScrollingAnimation
wydaje się uruchamiać tylko wtedy, gdy programowo przesuniesz widok przewijania, a nie, gdy użytkownik przewija.
Czy ktoś zna schemat wykrywania zakończenia przewijania widoku przewijania?
ios
iphone
uiscrollview
Michael Gaylord
źródło
źródło
Odpowiedzi:
źródło
Do 320 implementacje są o wiele lepiej - tutaj jest to poprawka, aby uzyskać spójne start / końce zwoju.
źródło
Myślę, że scrollViewDidEndDecelerating to ten, którego chcesz. Jego opcjonalna metoda UIScrollViewDelegates:
Informuje delegata, że widok przewijania zakończył spowolnienie ruchu przewijania.
Dokumentacja UIScrollViewDelegate
źródło
W przypadku wszystkich zwojów związanych z przeciąganiem interakcji będzie to wystarczające:
Teraz, jeśli przewijanie wynika z programowego setContentOffset / scrollRectVisible (z
animated
= YES lub oczywiście wiesz, kiedy przewijanie się zakończyło):Jeśli przyczyną przewijania jest coś innego (np. Otwarcie lub zamknięcie klawiatury), wydaje się, że będziesz musiał wykryć zdarzenie za pomocą hackowania, ponieważ również
scrollViewDidEndScrollingAnimation
nie jest przydatne.Przypadek widoku przewijania PAGINATED :
Ponieważ, jak sądzę, Apple stosuje krzywą przyspieszenia, jest
scrollViewDidEndDecelerating
wywoływany przy każdym oporze, więc nie ma potrzeby używaniascrollViewDidEndDragging
w tym przypadku.źródło
scrollViewDidEndDecelerating
nie zostanie wywołaneZostało to opisane w niektórych innych odpowiedziach, ale oto (w kodzie), jak połączyć
scrollViewDidEndDecelerating
iscrollViewDidEndDragging:willDecelerate
wykonać jakąś operację po zakończeniu przewijania:źródło
Dopiero co znalazłem to pytanie, które jest prawie takie samo, jak zadałem: Skąd dokładnie wiedzieć, kiedy zatrzymało się przewijanie UIScrollView?
Chociaż didEndDecelerating działa podczas przewijania, panoramowanie ze zwolnieniem stacjonarnym nie jest rejestrowane.
W końcu znalazłem rozwiązanie. didEndDragging ma parametr WillDecelerate, który jest fałszywy w przypadku zwolnienia stacjonarnego.
Sprawdzając! Decelerate w DidEndDragging, w połączeniu z didEndDecelerating, otrzymujesz obie sytuacje, które kończą przewijanie.
źródło
Jeśli interesujesz się Rx, możesz rozszerzyć UIScrollView w następujący sposób:
co pozwoli ci zrobić tak po prostu:
Uwzględni to zarówno przeciąganie, jak i zwalnianie.
źródło
źródło
Wypróbowałem odpowiedź Ashley Smart i zadziałała jak urok. Oto inny pomysł, z użyciem tylko scrollViewDidScroll
Miałem tylko dwie strony, więc zadziałało. Jeśli jednak masz więcej niż jedną stronę, może to być problematyczne (możesz sprawdzić, czy bieżące przesunięcie jest wielokrotnością szerokości, ale wtedy nie wiesz, czy użytkownik zatrzymał się na drugiej stronie, czy jest w drodze na trzecią lub więcej)
źródło
Szybka wersja zaakceptowanej odpowiedzi:
źródło
Jeśli ktoś potrzebuje, oto odpowiedź Ashley Smart w języku Swift
źródło
Właśnie opracowane rozwiązanie do wykrywania przewijania w całej aplikacji: https://gist.github.com/k06a/731654e3168277fb1fd0e64abc7d899e
Opiera się na idei śledzenia zmian trybów runloop. I wykonaj bloki co najmniej po 0,2 sekundy po przewinięciu.
Oto podstawowa idea śledzenia zmian trybów runloop iOS10 +:
I rozwiązanie dla małych celów wdrożeniowych, takich jak iOS2 +:
źródło
Podsumowując (i dla początkujących). To nie jest takie bolesne. Po prostu dodaj protokół, a następnie dodaj funkcje potrzebne do wykrywania.
W widoku (klasie), który zawiera UIScrolView, dodaj protokół, a następnie dodaj wszystkie funkcje z tego miejsca do swojego widoku (klasy).
źródło
Miałem przypadek stukania i przeciągania akcji i odkryłem, że przeciąganie wywoływało scrollViewDidEndDecelerating
Zmiana przesunięcia ręcznie za pomocą kodu ([_scrollView setContentOffset: contentOffset animated: YES];) wywoływała scrollViewDidEndScrollingAnimation.
źródło
Alternatywą byłoby użycie,
scrollViewWillEndDragging:withVelocity:targetContentOffset
które jest wywoływane za każdym razem, gdy użytkownik podniesie palec i zawiera docelowe przesunięcie zawartości, w którym przewijanie się zatrzyma. Użycie tego przesunięcia zawartości wscrollViewDidScroll:
prawidłowo identyfikuje, kiedy widok przewijania przestał się przewijać.źródło
UIScrollview ma metodę delegata
Dodaj poniższe wiersze kodu w metodzie delegata
źródło
Istnieje metoda,
UIScrollViewDelegate
której można użyć do wykrycia (lub lepiej powiedzieć „przewidywanie”), kiedy przewijanie naprawdę się zakończyło:z
UIScrollViewDelegate
których mogą być stosowane do wykrywania (lub lepiej powiedzieć „przewidzieć”) podczas przewijania naprawdę skończony.W moim przypadku użyłem go z przewijaniem poziomym w następujący sposób (w Swift 3 ):
źródło
Korzysta z logiki Ashley Smart i jest przekształcany w Swift 4.0 i nowsze.
Powyższa logika rozwiązuje problemy, takie jak przewijanie przez użytkownika widoku tabeli. Bez logiki, kiedy przewiniesz widok tabeli,
didEnd
zostanie wywołany, ale nic nie wykona. Obecnie używa go w roku 2020.źródło
W niektórych wcześniejszych wersjach iOS (takich jak iOS 9, 10)
scrollViewDidEndDecelerating
nie zostanie wyzwolony, jeśli scrollView zostanie nagle zatrzymany przez dotknięcie.Ale w obecnej wersji (iOS 13)
scrollViewDidEndDecelerating
na pewno zostanie uruchomiony (o ile wiem).Jeśli więc Twoja aplikacja była skierowana również do wcześniejszych wersji, możesz potrzebować obejścia takiego jak to, o którym wspomina Ashley Smart, lub możesz użyć następującego.
Wyjaśnienie
UIScrollView zostanie zatrzymany na trzy sposoby:
- szybko przewijany i zatrzymywany samoczynnie
- szybko przewijany i zatrzymywany przez dotknięcie palcem (jak hamulec awaryjny)
- powoli przewijany i zatrzymywany
Pierwszą można wykryć
scrollViewDidEndDecelerating
i innymi podobnymi metodami, podczas gdy dwie pozostałe nie.Na szczęście
UIScrollView
ma trzy stany, których możemy użyć do ich identyfikacji, które są używane w dwóch wierszach opatrzonych komentarzem „// 1” i „// 2”.źródło