2011-03-03 11 views
5

Tengo una situación similar a estas dos publicaciones (1907297 Y) y para describir mi situación de manera más concisa, presento este texto/diseño gráfico (similar a lo que ver en IB, puntos utilizados para imponer niveles de indentación)Pasar toques de deslizamiento desde UIView a UIScrollView subyacente para un desplazamiento correcto

UIView (MainView: 320x460)
. .UIScrollView (ScrollView: 320x460)
. .UIView (OverlayView: 320x40)
. . . .UIButton (ArbitraryButton1)
. . . .UILabel (ArbitraryLabel1)
. . . .UILabel (ArbitraryLabel2)

El objetivo aquí es que OverlayView sirva como un contenedor unificado y transparente para colocar y mostrar algunos botones/etiquetas arbitrarios encima de ScrollView. Estos botones/etiquetas deben permanecer estacionarios mientras el contenido en la Vista de desplazamiento debajo se mueve con toques de usuario. Los botones/etiquetas a veces pueden estar ocultos/ocultos/escalados al unísono (con animación), que es lo que hace que sea útil agruparlos en un solo OverlayView.

El problema es que, aunque los toques en el OverlayView parecen transmitirse directamente a ScrollView subyacente, los movimientos del deslizamiento no tienen ningún efecto. Puedo detectar/interceptar los golpes reemplazando el método

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 

en el OverlayView, sin embargo todavía no he encontrado una manera de pasar adecuadamente a lo largo de los a la ScrollView de una manera que hace que desplazarse. Evidentemente, el método touchesMoved no es lo que usa UIScrollView para detectar/interpretar golpes.

Todas las otras publicaciones similares que he investigado han encontrado una solución diferente que no funcionaría en mi caso o que acaba de quedar sin resolver. También he visto mencionar el uso de toquesShouldBegin/touchesShouldCancel, aunque no entiendo cómo se implementaría. De todos modos, aún con la esperanza de que haya algo de la comunidad que me permita encontrar una solución elegante para esto, cualquier código de muestra sería fantástico.

Gracias de antemano, Joel.

P.S. - También debería mencionar que necesito hacer que esto sea compatible con iOS 3.0, así que creo que está intentando usar UIGestureRecognizers.

+0

No creo que alguna vez resuelto este? – mahboudz

+0

¿Ya lo resolvió? –

Respuesta

0

¿Qué tal, en tiempo de ejecución en viewDidLoad, quita los botones de la vista de contenedor y los coloca en la vista como subvistas directamente (y se deshace de la vista de contenedor)? Entonces no hay vista de contenedor para interceptar toques, pero aún puede usar una vista para agrupar cosas en IB.

También podría poner potencialmente la vista de contenedor como una subvista de la vista de desplazamiento en su lugar, y en el delegado de la vista de desplazamiento mantener el reposicionamiento de la vista cada vez que el usuario se desplaza. Eso parece tener un alto potencial para estar nervioso, pero puede valer la pena intentarlo.

También si la vista que contiene es un contenedor visual y necesita verla, podría usar un CALayer que se colocó en la supervista en la parte superior del CALayer para representar la vista de desplazamiento, ya que los CALayers no tienen nada que ver con entrada y no toques cada uno.

0

Debe subclase UIScrollView y anular la touchesShouldCancelInContentView: Método

-(BOOL)touchesShouldCancelInContentView:(UIView *)view 
{ 

    if ([view isKindOfClass:[UIButton class]]) {//or whatever class you want to be able to scroll in 
     return YES; 
    } 

    if ([view isKindOfClass:[UIControl class]]) { 
     return NO; 
    } 

    return YES; 
} 
+0

Y, por supuesto, canCancelContentTouches debe establecerse en YES (que de forma predeterminada es SÍ, pero solo en caso de que alguien lo establezca en NO) –

0

He aquí un soluciones más fáciles que han funcionado bien para mí:

En el OverlayView (la vista en la parte superior de UIScrollView), la anchura y altura tanto 0 (para que la vista ya no esté técnicamente encima de la vista de desplazamiento) como set clipsToBounds = NO (de modo que el contenido de OverlayView aún aparezca en la parte superior de la vista de desplazamiento). Funcionó como un encanto para mí.

self.OverlayView.clipsToBounds = NO; 
CGRect frame = self.OverlayView.frame; 
self.OverlayView.frame = CGRectMake(frame.origin.x, frame.origin.y, 0, 0); 

Tenga en cuenta que si OverlayView contiene controles interactivos (como el botón de arriba), entonces ya no funcionarán. Tendrá que moverlo a su propia vista arriba de UIScrollView.

0

Necesitaba algo similar y después de investigar y leer la documentación de Apple, creé esta biblioteca de código abierto realmente simple y segura que resolverá su problema (MobileJoel). El proyecto de demostración utiliza una ScrollView por lo que se relaciona directamente:
https://github.com/natrosoft/NATouchThroughView

lo tanto, su jerarquía de vistas se vería así:

UIView (MainView: 320x460)  
. .UIScrollView (ScrollView: 320x460) 
. .UIView (OverlayView: 320x40) --> change this view to class NARootTouchThroughView in I.B. 
. . . .UIView (transparent UIView that you change to class NATouchThroughView in I.B.) 
. . . .UIButton (ArbitraryButton1) 
. . . .UILabel (ArbitraryLabel1) 
. . . .UILabel (ArbitraryLabel2) 

Así que, básicamente, su vista superposición enviará sus toques debajo de ella, que entonces conseguirá recibida por UIScrollview. Si sus UILabels son enormes y están interceptando toques, a continuación, colocar otra NATouchThroughView encima de ellos para que el resultado final es el siguiente:

UIView (MainView: 320x460)  
. .UIScrollView (ScrollView: 320x460) 
. .NARootTouchThroughView (OverlayView: 320x40) 
. . . .NATouchThroughView (transparent) 
. . . .UIButton (ArbitraryButton1) 
. . . .UILabel (ArbitraryLabel1) 
. . . .UILabel (ArbitraryLabel2) 
. . . .NATouchThroughView (transparent and covers the labels but not the UIButton) 
Cuestiones relacionadas