2011-11-06 25 views
5

El caso de prueba se reproduce fácilmente: descargue la aplicación de muestra PhotoScroller de Apple e intente adaptarla para que el paneo (tanto alrededor de una imagen ampliada como entre cada imagen) solo funcione con dos dedos .Paginación UIScrollView con dos dedos y zoom

Ajuste del panGestureRecognizer tanto para el pagingScrollView y la imageScrollView para aceptar sólo un mínimo & máximo de 2 toques que parece ser un buen punto de partida, sin embargo, no funciona. Te permite desplazarte por una imagen con dos dedos simplemente bien *, sin embargo, la búsqueda no funciona.

He intentado tantas combinaciones de configuraciones y reconocedores de gestos personalizados, y estoy un poco perplejo. ¿Va a ser de alguna utilidad una subclase de vista de desplazamiento personalizada, o puedo manipular de algún modo los métodos de delegado de la vista de desplazamiento para que funcione?

* EDITAR: En realidad, no se mueve bien en esta situación. La vista ya no se desliza suavemente como con un solo toque ...

ACTUALIZACIÓN: Todavía estoy luchando con este. Agradecería la contribución de alguien que haya jugado con UIGestureRecognizer sy UIScrollView s.

EDITAR:

Configuración de la clase ImageScrollView para aceptar sólo dos toques:

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

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

Configuración PhotoViewController 's pagingScrollView para aceptar sólo dos toques:

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

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

Estas modificaciones se hacen directamente en la parte superior de PhotoS aplicación de muestra croller. Es de esperar que estos simples cambios funcionen para la interacción de dos dedos, sin embargo, los efectos secundarios son extraños (como se explicó anteriormente).

+0

Descargando. 108mb o_O – 0xSina

+0

@PragmaOnce: Sí, siento vincular una muestra tan grande. Contiene todas las imágenes a tamaño completo y en mosaico para la vista de desplazamiento de paginación. No son necesarias imágenes bonitas para demostrar mi punto, ¡pero eh ...! – Stuart

+1

UIScrollView tiene sus propios reconocedores de gestos privados. Incluso el panGestureRecognizer expuesto es una clase privada. 'NSLog (@"% @ ", [pagingScrollView valueForKeyPath: @" gestureRecognizers.class "]);' -> '(UIScrollViewDelayedTouchesBeganGestureRecognizer, UIScrollViewPanGestureRecognizer, UIScrollViewPagingSwipeGestureRecognizer)'. Creo que deberás elegir una IU diferente. –

Respuesta

0

Parece que este es o bien imposible, o muy difícil (es decir rodar su propio punto de vista de desplazamiento desde cero). Usé un incidente de soporte de Apple Tech y no pudieron ayudar. Si hay una solución disponible, felizmente la marcaré como la respuesta aceptada.

+0

No es para nada imposible - solución fácil ... - ;-) Ver mi respuesta detallada ... – mramosch

0

subclases parece ser el camino a seguir con esta

La documentación indica que se puede manipular cómo los gestos de desplazamiento se manejan a través de subclases.

UIScrollView Class Reference

Específicamente

subclases pueden anular el touchesShouldBegin: withEvent: inContentView :, pagingEnabled, y touchesShouldCancelInContentView: métodos (que son llamadas por la vista de desplazamiento) para afectar a cómo el rollo vista maneja gestos de desplazamiento.

También debe echar un vistazo a este SO puesto, Scrolling with two fingers with a UIScrollView

+0

Gracias por la respuesta, lo agradezco. Sin embargo, siendo crítico por un minuto, esta es una respuesta muy genérica a una pregunta más específica. El 'ImageScrollView' ya está subclasificado, y he experimentado con la subclasificación de la vista de desplazamiento de paginación también, en vano. He visto la publicación SO vinculada anteriormente, y aunque me ha sido útil en el pasado, las respuestas son en realidad todas obsoletas (incluso las que iteran a través de los reconocedores de gestos de la vista desplazada; lo mismo puede lograrse más fácilmente en iOS 5). usando el código en mi pregunta). – Stuart

+0

Espero que pueda apreciar que me gustaría emitir el bounty a una respuesta que proporcione una visión más detallada de cómo se puede personalizar una subclase para lograr el comportamiento requerido. Por ejemplo, dado que 'touchesShouldBegin ...' & 'touchesShouldCancel ...' solo se invocan una vez al comienzo de cada secuencia táctil, ¿cómo manejo el caso en el que el 'ImageScrollView' debe panoramizarse (mientras se amplía), y luego la vista de desplazamiento de paginación debería hacerse cargo cuando el desplazamiento llega al borde de la imagen? – Stuart

+0

Puedo apreciarlo por completo, espero que pueda obtener una respuesta más útil. Veré si puedo investigar un poco. He usado reconocedores de gestos con scrollviews, pero no este escenario. –

0

PROBLEMA:

Cuando el UIPanGestureRecognizer subyace una UIScrollView (que desafortunadamente también afecta UIPageViewController) la maximumNumberOfTouches no se comporta como se esperaba - la minimumNumberOfTouches sin embargo, siempre lim es el extremo inferior correctamente.

Al monitorear estos parámetros, parecen hacer su trabajo; ¡simplemente es que UIScrollView no los respeta e ignora sus valores!


RECURSO:

puede encontrar la solución en mi respuesta a:

UIScrollView scrolling only with one finger


Por cierto:

La diferencia entre experimenta one dedo y two paneo dedo se debe a que con un dedo que está utilizando el panGestureRecognizer. Con dos dedos, el pinchGestureRecognizer (que también puede desplazarse al mismo tiempo) se activa y no tiene fase de desaceleración y la vista deja de girar y hacer zoom inmediatamente después de soltar los dedos. Desactivar el pinchGestureRecognizer y verá que el panGestureRecognizer se hace cargo - incluso para dos dedos - y la panorámica es suave otra vez ... ;-)


al mismo tiempo - et voilà ...

devoluciones de llamada de delegado para una perfecta dedo simultánea 2 scrolling y zooming comportamiento:

- (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 comienza a hacer zoom!
Fast pan ¡inicia el barrido!

Detener una bandeja de desaceleración con dos nuevos dedos en la pantalla y empezar a arrastrar de nuevo no deja que el torpe pellizcoRegistro se haga cargo (predeterminado) sino que pase suavemente a la siguiente fase de pan/desaceleración, ¡como con un dedo!


para perfeccionistas:

poner 2 dedos en la pantalla y - no se mueven EMPRESA - Si no se empieza pellizcos dentro de los primeros 0,5 segundos zooming se bloquea y solo panning está disponible:

- (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; 
} 

feliz gesto de reconocimiento!


Cuestiones relacionadas