2013-02-11 9 views
5

Muszę otrzymać powiadomienie, gdy przeciągnięty zostanie koniec przeciągnięcia.Jak wykrywać zdarzenie końca przeciągania w widoku UITableView?

Ale pracuję nad kategorią UITableView, więc nie mogę użyć scrollViewDidEndDragging:willDecelerate:, aby to zarchiwizować.

Próbowałem użycie KVO obserwować na dragging Key Path:

[self addObserver:self forKeyPath:@"dragging" options:NSKeyValueObservingOptionNew context:nil]; 

Ale observeValueForKeyPath:ofObject:change:context: nie sprawdzony, ponieważ UITableView.dragging nie ma i setter i właściwość ta nie jest zgodny z KVO.

Czy istnieje inna metoda archiwizacji, której można się spodziewać przy użyciu scrollViewDidEndDragging:willDecelerate:?

Każda pomoc jest wdzięczna! Dzięki!

Odpowiedz

8

Edit: poniżej Moje rozwiązanie było pierwszą rzeczą, aby przyjść na uwadze i okazał się być dość hacky i może być niebezpieczne w użyciu w przypadku firmy Apple zdecyduje się zmienić wewnętrzne klasy UIScrollView. Zobacz propozycję answer zaproponowaną przez Mazyod, która powinna być bezpieczniejsza i bardziej prosta.


To jest zależna od implementacji i mogą być zmieniane przez Apple w przyszłych aktualizacjach iOS, ale obecnie UIScrollView klasa wydaje się polegać na Recognizers gest za zarządzanie interakcji użytkownika i UITableView jest podklasą klasy widoku przewijania robi to samo .

Jeśli pójdziesz do UIScrollView.h ram UIKit można zauważyć podejrzaną _pan ivar która ma typ id, ale wydaje się być rzeczywiście UIPanGestureRecognizer.

Próbowałem tego i wydaje się, że działa.

[_tableView addObserver: self 
       forKeyPath: @"pan.state" 
       options: NSKeyValueObservingOptionNew 
       context: nil]; 

Podczas przeciągania widoku tabeli, state z rozpoznawania gestów zmienia się kilka razy, a kiedy przestać przeciągania state otrzymuje swoją ostatnią zmianę do wartości UIGestureRecognizerStateEnded.

Należy pamiętać, że chociaż wydaje się, że to wystarczy, to jednak na przeszkodzie może stanąć inny problem. Generalnie nie jest dobrym pomysłem zastąpienie istniejących metod klasy w kategorii, ponieważ pierwotna implementacja staje się później niedostępna. Dokumentacja na nieformalnym protokołu NSKeyValueObserving stwierdza, że ​​

NSObject zapewnia implementację protokołu NSKeyValueObserving który zapewnia automatyczną zdolność obserwacji dla wszystkich obiektów.

Więc jeśli przesłonić observeValueForKeyPath:ofObject:change:context: w kategorii domyślna implementacja będzie niedostępne (i nie możemy być pewni, że UITableView lub UIScrollView nie KVO użytkownika za coś). Może to spowodować nieoczekiwane błędy.

+0

Jak wdrożyć 'observeValueForKeyPath: ofObject: change: context:' w niektórych klasach 'Foo', a kategoria UITableView zachować instancję Foo? – OpenThread

+0

Dzięki za pomoc! Twoja odpowiedź jest dla mnie pomocna! – OpenThread

+1

Implementacja 'observeValueForKeyPath: ofObject: change: context:' w oddzielnej klasie Foo powinna rzeczywiście pomóc w rozwiązaniu problemu "nadpisując istniejącą metodę w kategorii". –

8

Odpowiedź Egora Chiglintseva przypomniała mi, że mogę obserwować nieruchomość już wystawioną w , która została już ujawniona w UIScrollView. Powinno być znacznie bezpieczniejsze niż pan. Ale potem ... Dowiedziałem się, że mogę dodać siebie jako cel!

[_scrollView.panGestureRecognizer addTarget:self action:@selector(gestureRecognizerUpdate:)]; 

Działa to doskonale dla mnie!

+1

Myślę, że to właściwy sposób, w jaki powinien być naprawdę zrobiony. Nie wiem, dlaczego pierwsze rzeczy, które przychodzą mi do głowy, to zazwyczaj jakieś hacki związane z runtime lub KVO. Dzięki) –

Powiązane problemy