2011-11-06 16 views
5

Etui testowe jest łatwe do odtworzenia: pobierz przykładową aplikację Apple PhotoScroller i spróbuj ją dostosować, tak aby przesuwanie (zarówno wokół powiększonego obrazu, jak i pomiędzy zdjęciami) działa tylko na dwóch palcach .Paging UIScrollView z przesuwaniem dwoma palcami i powiększeniem

Ustawianie panGestureRecognizer zarówno dla pagingScrollView i imageScrollView do jedynie zaakceptować min & max 2 akcentów wydaje się dobrym miejscem do rozpoczęcia, jednak nie działa. Pozwala przewijać obraz dwoma palcami, bez względu na to, jak działa stronicowanie.

Próbowałem już wielu kombinacji ustawień i niestandardowych rozpoznawania gestów, a ja jestem trochę zakłopotany. Czy niestandardowa podklasa widoków przewijania ma jakiekolwiek zastosowanie, czy też mogę w jakiś sposób manipulować metodami delegatów widoku przewijania, aby to działało?
* EDYCJA: W rzeczywistości nie przewija się dobrze w tej sytuacji. Widok nie przesuwa się gładko, jak jednym dotknięciem ...

AKTUALIZACJA: Nadal borykam się z tym. Byłbym wdzięczny za informacje od kogoś, kto bawił się z UIGestureRecognizer s i UIScrollView s.

EDIT:

Ustawienie klasę ImageScrollView przyjąć tylko dwie poprawki:

- (id)initWithFrame:(CGRect)frame 
{ 
    // ... 
    // Template code 
    // ... 

    [self.panGestureRecognizer setMinimumNumberOfTouches:2]; 
    [self.panGestureRecognizer setMaximumNumberOfTouches:2]; 
} 

Ustawianie PhotoViewController „s pagingScrollView przyjąć tylko dwie poprawki:

- (void)loadView 
{ 
    // ... 
    // Template code 
    // ... 

    [pagingScrollView.panGestureRecognizer setMinimumNumberOfTouches:2]; 
    [pagingScrollView.panGestureRecognizer setMaximumNumberOfTouches:2]; 
} 

Te modyfikacje są wykonane bezpośrednio na PhotoS próbna aplikacja croller. Spodziewam się, że te proste zmiany zadziałają w przypadku interakcji dwóch palców, jednak efekty uboczne są dziwne (jak wyjaśniono powyżej).

+0

Pobieranie. 108mb o_O – 0xSina

+0

@PragmaOnce: Tak, przykro mi linkować tak dużą próbkę. Zawiera wszystkie obrazy w pełnym rozmiarze i kafelki dla widoku przewijania stronicowania. Ładne zdjęcia nie są konieczne, aby pokazać mój punkt widzenia, ale hej ...! – Stuart

+1

UIScrollView ma własne, prywatne detektory gestów. Nawet odsłonięty panGestureRecognizer jest prywatną klasą. 'NSLog (@"% @ ", [pagingScrollView valueForKeyPath: @" gestureRecognizers.class "]);' -> '(UIScrollViewDelayedTouchesBeganGestureRecognizer, UIScrollViewPanGestureRecognizer, UIScrollViewPagingSwipeGestureRecognizer)'. Myślę, że musisz wybrać inny interfejs. –

Odpowiedz

0

Wydaje się, że to jest niemożliwe lub bardzo trudne (tj toczyć własną przewijania widoku od podstaw). Użyłem incydentu wsparcia technicznego Apple Tech i nie byli w stanie ci pomóc. Jeśli rozwiązanie stanie się dostępne, z radością oznaczę to jako zaakceptowaną odpowiedź!

+0

Wcale niemożliwe - łatwa naprawa ... - ;-) Zapoznaj się ze szczegółową odpowiedzią ... – mramosch

0

Utworzenie podklasy wydaje się do zrobienia z tym

Dokumentacja mówi, że można manipulować jak przewijanie gesty są obsługiwane przez podklasy.

UIScrollView Class Reference

Szczególnie

podklasy mogą przesłonić touchesShouldBegin: withEvent: inContentView :, pagingEnabled i touchesShouldCancelInContentView: metody (które nazywane są przez widoku przewijania), aby wpłynąć na sposób zwój przeglądaj uchwyty, przewijając gesty.

Należy również zapoznać się z tym SO post, Scrolling with two fingers with a UIScrollView

+0

Dzięki za odpowiedź, doceniam to. Jednak - będąc krytycznym przez chwilę - jest to bardzo ogólna odpowiedź na bardziej szczegółowe pytanie. 'ImageScrollView' jest już podklasowany i eksperymentowałem z podklasowaniem widoku przewijania stronicowania, bez skutku. Widziałem wcześniej związany post SO i chociaż było to dla mnie przydatne w przeszłości, odpowiedzi są w rzeczywistości przestarzałe (nawet te, które są iterowane za pomocą rozpoznawania gestów w widoku przewijania - to samo można łatwiej osiągnąć w iOS 5 używając kodu w moim pytaniu). – Stuart

+0

Mam nadzieję, że docenisz to, że chciałbym wydać nagrodę za odpowiedź, która zapewnia nieco bardziej szczegółowy wgląd w to, jak można dostosować podklasę, aby osiągnąć wymagane zachowanie. Na przykład, ponieważ 'touchesShouldBegin ...' i 'touchesShouldAnuluj ...' są wywoływane tylko raz na początku każdej sekwencji dotykowej, w jaki sposób mogę obsłużyć przypadek, w którym 'ImageScrollView' powinien przesuwać (podczas powiększania), a następnie przewijanie stronicowania powinno przejąć kontrolę, gdy przewijanie osiągnie krawędź obrazu? – Stuart

+0

Mogę to w pełni docenić, mam nadzieję, że możesz uzyskać bardziej pomocną odpowiedź. Zobaczę, czy mogę w to trochę zaglądnąć. Użyłem rozpoznawania gestów z przewijaniem, ale nie w tym scenariuszu. –

0

PROBLEM:

Gdy UIPanGestureRecognizer jest będącym podstawą UIScrollView (co niestety ma również efekt UIPageViewController) maximumNumberOfTouches nie zachowuje się zgodnie z oczekiwaniami - na minimumNumberOfTouches jednak zawsze lim jego dolny koniec prawidłowo.

Monitorowanie tych parametrów wydaje się wykonywać swoją pracę - po prostu UIScrollView nie honoruje ich i ignoruje ich wartości!


ROZWIĄZANIE:

można znaleźć rozwiązanie w mojej odpowiedzi do:

UIScrollView scrolling only with one finger


BTW:

Różnica wystąpić między one palcem i two palca panoramowanie dlatego jednym palcem używasz panGestureRecognizer. Za pomocą dwóch palców można kopać i nie można wykonywać fazy zwalniania, a widok zatrzymuje przesuwanie i powiększanie natychmiast po zwolnieniu palców. Dezaktywować pinchGestureRecognizer i widać, że panGestureRecognizer przejmuje - nawet na dwa palce - i panoramowanie jest znowu gładkie ... ;-)


JEDNOCZEŚNIE - et voilà ...

callbacks Delegat doskonałego jednoczesne 2 palca scrolling i zooming zachowanie:

- (void)scrollViewWillBeginDragging:(UIScrollView *)scrollView { 
    self.pinchGestureRecognizer.enabled = NO; 
} 

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView { 
    self.pinchGestureRecognizer.enabled = NO; 
} 

- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate { 
    self.pinchGestureRecognizer.enabled = YES; 
} 

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView { 
    self.pinchGestureRecognizer.enabled = YES; 
} 

- (void)scrollViewWillBeginZooming:(UIScrollView *)scrollView withView:(UIView *)view {  
    self.panGestureRecognizer.enabled = NO; 
} 

- (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)view atScale:(CGFloat)scale {  
    self.panGestureRecognizer.enabled = YES; 
} 

Fast pinch rozpoczyna powiększanie!
Fast pan rozpoczyna przesuwanie!

Zatrzymanie miski spowalniającej dwoma nowymi palcami w dół ekranu i rozpoczęcie przeciągania ponownie nie pozwala przejąć niezdarnej szczypceGestureRecognizer (domyślnie), ale raczej płynnie przejść do kolejnej fazy pan/deceleration - jak jednym palcem!


DLA perfekcjonistów:

umieścić 2 palce na ekranie i - nie ruszają TERAZ - Jeśli nie zaczniemy szczypanie w ciągu pierwszych 0,5 sekundy zooming zostaje zablokowany i tylko panning jest dostępny:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer { 

    if ([gestureRecognizer.view isMemberOfClass:[MY_CustomScrollView class]]) { 

     NSLog(@"IN SCROLL-VIEW..."); 
     if (gestureRecognizer == self.pinchGestureRecognizer) { 
      if (_pinchGestureLocked) { 
       NSLog(@"...but TOO late for zooming..."); 
       return NO; 
      } else { 
       NSLog(@"...ZOOMING + PANNING..."); 
       return YES; 
      } 
     } else if (gestureRecognizer == self.panGestureRecognizer){ 
      if (gestureRecognizer.numberOfTouches > 2) { 
       NSLog(@"...but TOO many touches for PANNING ONLY..."); 
       return NO; 
      } else { 
       NSLog(@"...PANNING..."); 
       return YES; 
      } 
     } else { 

      NSLog(@"...NO PAN or PINCH..."); 
      return YES; 
     } 

    } else { 
     NSLog(@"NOT IN SCROLL-VIEW..."); 
    } 

    return YES; 

} 

BOOL _pinchGestureLocked = NO; 

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 
    [super touchesBegan:touches withEvent:event]; 
    _pinchGestureLocked = YES; 
} 

- (void) touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 
    [super touchesCancelled:touches withEvent:event]; 
    _pinchGestureLocked = NO; 
} 

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { 
    [super touchesEnded:touches withEvent:event]; 
    _pinchGestureLocked = NO; 
} 

Szczęśliwy gest uznając!


Powiązane problemy