Adelante toca y gestiona vistas desde UIScrollview

Tengo algunos problemas con el reenvío de gestos y toques. Jugué un poco con eso, pero no puedo hacerlo funcionar como quiero.

Básicamente, quiero controlar una vista de desplazamiento en una pantalla dual con 2 dedos y reenviar todo lo demás a las vistas de ipad detrás de una vista de desplazamiento superpuesta.

Para poder controlar la vista de desplazamiento en la pantalla doble I subclasificada UIScrollView y agregarla como una vista de superposition con un background claro a la pantalla del ipad.

Luego lo conecté con un delegado para reenviar su arrastre y esas cosas a la vista de desplazamiento en la pantalla dual. esto funciona perfectamente

Cuando escribí quiero que la vista de desplazamiento responda solo con 2 desplazamientos con los dedos, así que la puse a

 ScrollView.panGestureRecognizer.minimumNumberOfTouches = 2; 

Pero el scrollview come todos los toques y no lo hago bien para reenviar todo lo demás, pero dos toques de los dedos a las vistas detrás. Creo que anula la

 - (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 

debe hacer el truco, pero no lo hago bien para detectar la cantidad de dedos en la pantalla a la derecha.

Me gustaría compartir / explicar la solución al problema. Dicho esto, también quiero señalar que la input de hatfinch me condujo en la dirección correcta. ¡Muchas gracias, amigo!

El problema al intentar poner una vista / scrollview como capa superpuesta es que el superpodero no sabe acerca de su "próximo respondedor". al colocar la vista / scrollview como una vista inferior, se solucionará este problema. es posible que necesite ajustar el comportamiento táctil de cualquier vista de desplazamiento dentro de la vista de desplazamiento subyacente para get el comportamiento correcto (como establecer la cantidad máxima de toques)

La solución es subclasificar una UIScrollview, anular estos methods anular los toquesBegan: y otros methods táctiles de la siguiente manera (ver la respuesta del usuario1085093), y agregarlo como vista subyacente a la pantalla del ipad.

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

Hice la configuration de scrollview así:

  TopLayerScrollView *newScrollView = [[TopLayerScrollView alloc] init]; [newScrollView setBackgroundColor:[UIColor clearColor]]; [newScrollView setFrame:self.tabBarController.view.frame]; [newScrollView setContentSize:dualScreenViewController.scrollContent.contentSize]; newScrollView.showsHorizontalScrollIndicator = NO; newScrollView.showsVerticalScrollIndicator = NO; newScrollView.delegate = self; newScrollView.bounces = NO; [newScrollView scrollsToTop]; newScrollView.panGestureRecognizer.minimumNumberOfTouches = 2; self.topLayerScrollView = newScrollView; [newScrollView release]; [self.tabBarController.view removeFromSuperview]; [topLayerScrollView addSubview:self.tabBarController.view]; [window addSubview:topLayerScrollView]; [topLayerScrollView bringSubviewToFront:self.tabBarController.view]; 

El método de delegado de la scrollview subyacente:

 - (void)scrollViewDidScroll:(UIScrollView *)scrollView{ if (scrollView.dragging || scrollView.tracking) { [dualScreenViewControlleremphasized text.scrollContent setContentOffset:CGPointMake(scrollView.contentOffset.x, scrollView.contentOffset.y) animated:NO]; self.tabBarController.view.frame = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, self.tabBarController.view.frame.size.width, self.tabBarController.view.frame.size.height); }} 

Esta solución funciona muy bien. La otra solución sería tener una vista de desplazamiento como una vista de superposition como lo intenté por primera vez. Como se dijo, el problema es permitir que la vista de capa superior conozca las vistas (nextResponder). Para lograr esto, debe subcolumnar UIScrollview y crear una propiedad UESponder-responsive que debe conectar en su file de generador de interfaz o durante el time de ejecución. De esta manera, la superposition scrollview sabrá quién es el próximo respondedor. por favor vea la respuesta de morningstar

Desafortunadamente, no puedes hacer nada con -pointInside:withEvent: aquí porque el sistema decide en qué vista está el toque (o qué vistas están los toques) antes de determinar si cumplen los requisitos del reconocimiento de gestos.

Creo que lo mejor que puede hacer aquí es que la vista que está actualmente detrás de la vista de desplazamiento sea la vista de contenido de la vista de desplazamiento y que mueva esa vista cada vez que el desplazamiento de contenido de la vista de desplazamiento cambie para mantenerlo en la misma position en el pantalla. (Esto suena caro, pero no es realmente). Entonces, en lugar de ser una superposition, su vista de desplazamiento es más como una subposition.

También puede desear jugar con UIScrollView.delaysContentTouches , -[UIScrollView touchesShouldBegin:withEvent:inContentView:] , etc. para refinar el comportamiento.

Actualización para Xcode 6.4, Swift 1.2:

También subclasé UIScrollView :

 import UIKit class WBMScrollView: UIScrollView { override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) { self.nextResponder()?.touchesBegan(touches, withEvent: event) super.touchesBegan(touches, withEvent: event) } } 

En la aplicación vc ViewController.swift principal, la probé en:

 override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) { println(" touches began") } 

Y funcionó. La vista de desplazamiento se ha agregado a través de IB y se ha conectado a ViewController.swift

Con mi aplicación, necesitaba events con un solo dedo para que se reenvía al controller de vista principal de la vista de desplazamiento, mientras que permite que la vista de desplazamiento se acerque o aleje.

Usar el siguiente respondedor no funcionó porque también estoy agregando otra vista superpuesta que termina convirtiéndose en el próximo respondedor y robando los events táctiles. Terminé haciendo algo basado en la respuesta de Tom simplemente pasando el controller de vista principal y enviando events táctiles directamente a él. Aquí está en Swift:

 class CustomScrollView: UIScrollView { var parentViewController: UIViewController? override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { parentViewController?.touchesBegan(touches, with: event) } override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) { parentViewController?.touchesMoved(touches, with: event) } override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) { parentViewController?.touchesEnded(touches, with: event) } }