2010-09-04 10 views
43

Tengo un pequeño problema en mi aplicación.UIButton touch se retrasa cuando en UIScrollView

Básicamente tengo una serie de UIButtons agregada como subvistas en un UIScrollView que es parte de un plumín. Cada vez que toco un botón, hay un retraso notable antes de que se resalte el botón. En esencia, tengo que mantenerlo durante aproximadamente medio segundo antes de que el botón se atenúe y aparezca seleccionado.

Supongo que esto se debe a que el UIScrollView necesita determinar si el toque es un desplazamiento o si se trata de un toque destinado a una subvista.

De todos modos, no estoy seguro de cómo proceder. Simplemente quiero que el botón aparezca seleccionado tan pronto como lo toque.

¡Se agradece cualquier ayuda!

Editar:

He tratado de establecer delaysContentTouches-NO pero el desplazamiento se convierte en casi imposible ya que la mayoría de mi ScrollView está lleno de UIButtons.

+0

Considera retirar esta respuesta en lugar de la aceptada: http://stackoverflow.com/a/19656611/378024 – galambalazs

Respuesta

39

Ok He resuelto este subclasificando UIScrollView y primordial touchesShouldCancelInContentView

Ahora mi UIButton que fue etiquetada como 99 destacados correctamente y mi ScrollView se desplaza!

myCustomScrollView.h:

@interface myCustomScrollView : UIScrollView { 

} 

@end 

y myCustomScrollView.m:

@implementation myCustomScrollView 

    - (BOOL)touchesShouldCancelInContentView:(UIView *)view 
    { 
     NSLog(@"touchesShouldCancelInContentView"); 

     if (view.tag == 99) 
      return NO; 
     else 
      return YES; 
    } 
+6

Wow, acabo de encontrar esta respuesta y resolvió completamente el problema que estaba teniendo. ¡Ojalá pudiera darte +1000 puntos! Muchas gracias. –

+0

no funciona en mi caso, pero está muy cerca de ti. (Probado solo en el simulador). Tal vez este tiempo de solución se acabe. –

+0

Swift versión abajo, sigue leyendo ... –

25

Intente configurar la propiedad UIScrollView delaysContentTouches en NO.

+1

Lo siento, probablemente debería haber sido más claro. Si configuro delayysContentTouches en NO, el toque responde de inmediato. Sin embargo, el desplazamiento se vuelve prácticamente imposible, ya que los toques se interpretan como pulsaciones de botones en lugar de desplazamiento real. – Jeff

+0

@Jeff Puede usar 'canCancelContentTouches' para permitir el desplazamiento incluso si el toque se trata inicialmente como un botón táctil, siempre y cuando los objetivos del toque admitan la cancelación. Los botones aún se resaltarán inicialmente cuando se toquen, pero tan pronto como comience a desplazarse, se destellará. – devios1

+0

@chaiguy Estoy buscando este comportamiento, exactamente como usted lo describió, pero hasta ahora no ha habido suerte. Si configuro 'delaysContentTouches = NO' y' canCancelContentTouches = YES', no puedo desplazarme al tocar UIButton. – Darrarski

0

Ninguna de las soluciones existentes trabajó para mí. Tal vez mi situación es más única.

Tengo muchos UIButtons dentro de un UIScrollView. Cuando se presiona UIButton, se presenta al usuario un nuevo UIViewController. Si se presiona un botón y se mantiene presionado el tiempo suficiente, el botón mostrará su estado deprimido. Mi cliente se quejaba de que si toca demasiado rápido, no se muestra ningún estado deprimido.

Mi solución: Dentro del método UIButtons 'del grifo, en el que cargar el nuevo UIViewController y presentarla en la pantalla, utilizo

[self performSelector:@selector(loadNextScreenWithOptions:) 
      withObject:options 
      afterDelay:0.] 

Este programa la carga de la siguiente UIViewController en el siguiente bucle de eventos. Permitir tiempo para el UIButton para volver a dibujar. El UIButton ahora muestra su estado deprimido antes de cargar el siguiente UIViewController.

37

solución de Jeff no estaba trabajando para mí, pero esto una similar hace: http://www.charlesharley.com/2013/programming/uibutton-in-uitableviewcell-has-no-highlight-state/

No estoy seguro si este fue el caso de la respuesta de Jeff, pero además de anular -touchesShouldCancelInContentView: en la vista de desplazamiento subclase, todavía necesita establecer delaysContentTouches en NO. Por último, en lugar de devolver NO para sus botones, debe devolver YES. Aquí hay un ejemplo del enlace de arriba.

- (instancetype)initWithFrame:(CGRect)frame { 
    if (self = [super initWithFrame:frame]) { 
     self.delaysContentTouches = NO; 
    } 

    return self; 
} 

- (BOOL)touchesShouldCancelInContentView:(UIView *)view { 
    if ([view isKindOfClass:UIButton.class]) { 
     return YES; 
    } 

    return [super touchesShouldCancelInContentView:view]; 
} 

Swift version.

override func touchesShouldCancelInContentView(view: UIView!) -> Bool { 
    if view is UIButton { 
     return true 
    } 
    return super.touchesShouldCancelInContentView(view) 
} 
+3

esto funciona para mí y no es la respuesta aceptada. Gracias. –

+3

¡Excelente solución! Si está utilizando el constructor de interfaces, simplemente seleccione scrollView y desmarque 'demora el contenido toques' en el inspector de atributos. – Tim

+1

¡Trabaja para mí! Gracias. – frank

0

solución Storyboard: Seleccione la vista de desplazamiento, abra el "Atributos Inspector" y desactive "retrasos Toques contenido"

enter image description here

0

Swift 3:

scrollView.delaysContentTouches = false 
1

En Swift 3 :

import UIKit 

class ScrollViewWithButtons: UIScrollView { 

    override init(frame: CGRect) { 
     super.init(frame: frame) 
     myInit() 
    } 

    required init?(coder aDecoder: NSCoder) { 
     super.init(coder: aDecoder) 
     myInit() 
    } 

    private func myInit() { 
     self.delaysContentTouches = false 
    } 

    override func touchesShouldCancel(in view: UIView) -> Bool { 
     if view is UIButton { 
      return true 
     } 
     return super.touchesShouldCancel(in: view) 
    } 
} 

Puede usar este ScrollViewWithButtons en IB o en el código.

Cuestiones relacionadas