2011-09-16 5 views
26

Estoy manejando toques para un par de mis componentes de UI en mi controlador de vista (subclase personalizada de UIViewController). Tiene los métodos touchesBegan:withEvent:, touchesMoved:withEvent: y touchesEnded:withEvent:. Funcionaba bien Luego agregué una vista de desplazamiento (UIScrollView) como la vista superior en la jerarquía.UIScrollView previene los toquesBegan, touchesMoved, touchesEnded en el controlador de vista

Ahora mis controladores táctiles en el controlador de vista no funcionan. Ellos no son llamados. Lo interesante es que tengo varios otros componentes de UI dentro de la vista de desplazamiento que sí funcionan. Algunos son botones, algunos son vistas personalizadas que definen su propio touchesBegan:withEvent:, etc. Lo único que no funciona son los controladores táctiles en el controlador de vista.

pensé que tal vez es porque la vista de desplazamiento está interceptando los toques para sus propios fines, pero con subclases UIScrollView y sólo para ver si podía conseguir que funcione estoy regresando YES siempre desde touchesShouldBegin:withEvent:inContentView: y NO siempre desde touchesShouldCancelInContentView:. Aún no funciona.

Si hace una diferencia mi controlador de vista está dentro de un controlador de barra de pestañas, pero no creo que sea relevante.

¿Alguien ha tenido este problema y tiene una solución preparada? Mi suposición es que los monos de la vista de desplazamiento suben por la cadena de respuesta. ¿Puedo volver a montarlo? Supongo que si no puedo entender nada más, haré que la vista de nivel superior en mi vista de desplazamiento sea una vista personalizada y reenvíe los mensajes al controlador de vista, pero parece kludgy.

+0

seguir mi respuesta aquí http://stackoverflow.com/questions/1685956/uiscrollview-touchesbegan/17759373# 17759373 – Rajneesh071

Respuesta

0

"Funcionó bien. Luego agregué una vista de desplazamiento (UIScrollView) como la vista superior en la jerarquía."

¿es su vista de desplazamiento en la parte superior de su contenido que contiene elementos?

todos sus componentes deben estar en el ScrollView y no la vista detrás de la ScrollView

+0

Superior como jerárquicamente en la parte superior. Como en todas las otras vistas son subvistas de la vista de desplazamiento. Bueno, específicamente hay una vista que es una subvista de la vista de desplazamiento, y todas las otras son subvistas de eso, o subvistas de subvistas, etc. – morningstar

2

Bueno este trabajado, pero no estoy seguro de que puedo "salirse con la suya", ya que nextResponder no es uno de los UIView métodos que se recomienda "anular" en una subclase.

@interface ResponderRedirectingView : UIView { 

    IBOutlet UIResponder *newNextResponder; 

} 

@property (nonatomic, assign) IBOutlet UIResponder *newNextResponder; 

@end 


@implementation ResponderRedirectingView 

@synthesize newNextResponder; 

- (id)initWithFrame:(CGRect)frame 
{ 
    self = [super initWithFrame:frame]; 
    if (self) { 
     // Initialization code 
    } 
    return self; 
} 

- (UIResponder *)nextResponder { 
    return self.newNextResponder; 
} 

- (void)dealloc 
{ 
    [super dealloc]; 
} 

@end 

Luego, en el Interface Builder Hice la subvista directa de la vista de desplazamiento uno de estos, y enganchado hasta su newNextResponder para saltar el ScrollView y apuntar directamente al controlador de vista.

Esto funciona también, la sustitución de la anulación de nextResponder con estas anulaciones:

- (void) touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    [self.newNextResponder touchesBegan:touches withEvent:event]; 
} 

- (void) touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 
    [self.newNextResponder touchesMoved:touches withEvent:event]; 
} 

- (void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { 
    [self.newNextResponder touchesEnded:touches withEvent:event]; 
} 

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { 
    [self.newNextResponder touchesCancelled:touches withEvent:event]; 
} 
-1

Los métodos touchesBegan: etc serán NUNCA ser llamados en un UIScrollView, ya que es una subclase de UIView y prevalece sobre estos métodos. echa un vistazo a los diferentes métodos UIScrollView disponibles here. La solución dependerá de lo que quiera implementar.

+0

No se trata de métodos touchesBegan en la vista de desplazamiento que no se están llamando. Están en mi controlador de vista. Por otro lado, los toques comienzan en las vistas que están "en" donde se está llamando a la vista de desplazamiento. Es un problema bastante opuesto. No pueden "salir" de la vista de desplazamiento. – morningstar

+0

Todavía no recibí tu pregunta por completo, aunque me gustaría señalar que el método touchesBegan ¡funcionará para una vista dentro de un scrollView! – tipycalFlow

+0

He revisado la documentación de UIScrollView y UIScrollViewDelegate y he probado lo que está disponible. Lo que trato de hacer varía desde un simple gesto de toque hasta una interpretación compleja de toques como resaltar un área de la pantalla. Podría cambiarlo a reconocedores de gestos y eso probablemente solucionaría el problema, pero a) No quiero volver a escribir el código b) Quiero que se ejecute en 3.0, que no tenía reconocedores de gestos. – morningstar

22

crear una subclase de la clase UIScrollView y redefinir la touchesBegan: y otros métodos táctiles de la siguiente manera: Respuesta

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ 

// If not dragging, send event to next responder 
    if (!self.dragging){ 
    [self.nextResponder touchesBegan: touches withEvent:event]; 
    } 
    else{ 
    [super touchesBegan: touches withEvent: event]; 
    } 
} 
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ 

// If not dragging, send event to next responder 
    if (!self.dragging){ 
    [self.nextResponder touchesMoved: touches withEvent:event]; 
    } 
    else{ 
    [super touchesMoved: touches withEvent: event]; 
    } 
} 
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event{ 

    // If not dragging, send event to next responder 
    if (!self.dragging){ 
    [self.nextResponder touchesEnded: touches withEvent:event]; 
    } 
    else{ 
    [super touchesEnded: touches withEvent: event]; 
    } 
} 
+2

¿Es seguro hacer esto en una categoría en lugar de subclasificar? –

+0

¡Gracias, hasta ahora mi categoría (de su código) funciona perfectamente en mi aplicación! –

0

de user1085093 trabajó para mí. Sin embargo, una vez que mueves el toque más de una pequeña cantidad, se interpreta como un gesto de desplazamiento.

superé esta alterando el comportamiento del reconocedor Gesto Pan por lo que requiere dos dedos:

-(void)awakeFromNib 
{ 
    NSArray     *gestureRecognizers = self.gestureRecognizers; 
    UIGestureRecognizer  *gestureRecognizer; 

    for (gestureRecognizer in gestureRecognizers) { 
     if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { 
      UIPanGestureRecognizer  *pgRecognizer = (UIPanGestureRecognizer*)gestureRecognizer; 
      pgRecognizer.minimumNumberOfTouches = 2; 
     } 
    } 

} 
Cuestiones relacionadas