UIButton touch se retrasa cuando está en UIScrollView


Me estoy topando con un pequeño problema en mi aplicación.

Esencialmente tengo una serie de UIButtons agregados como subviews en un UIScrollView que es parte de un plumín. Cada vez que toco un botón hay un retardo notable antes de que el botón se resalte. Esencialmente tengo que mantenerlo durante aproximadamente medio segundo antes de que el botón se atenúe y aparezca seleccionado.

Asumo que esto se debe a que el UIScrollView necesita determinar si el toque es un pergamino o si es un toque que está destinado a un subview.

De todos modos, estoy un poco inseguro sobre cómo proceder. Simplemente quiero que el botón aparezca seleccionado tan pronto como lo toque.

Cualquier ayuda es apreciada!

Editar:

He intentado establecer delaysContentTouches a NO pero el desplazamiento se vuelve casi imposible ya que la mayoría de mi vista de desplazamiento está llena de UIButtons.

Author: twernt, 2010-09-04

7 answers

La solución de Jeff no estaba funcionando para mí, pero esta similar sí:http://charlesharley.com/2013/programming/uibutton-in-uitableviewcell-has-no-highlight-state

Además de sobreescribir touchesShouldCancelInContentView en su subclase de vista de desplazamiento, todavía necesita establecer delaysContentTouches a false. Por último, debe devolver true en lugar de false para sus botones. Aquí hay un ejemplo modificado del enlace anterior. Como los comentaristas sugirieron, comprueba cualquier subclase de UIControl en lugar de UIButton específicamente para que este comportamiento se aplique a cualquier tipo de control.

Objetivo-C:

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

    return self;
}

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

    return [super touchesShouldCancelInContentView:view];
}

Swift 4:

override func touchesShouldCancel(in view: UIView) -> Bool {
    if view is UIControl {
        return true
    }
    return super.touchesShouldCancel(in: view)
}
 44
Author: jlong64,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-09-30 03:03:06

Ok He resuelto esto subclasificando UIScrollView y anulando touchesShouldCancelInContentView

Ahora mi UIButton que fue etiquetado como 99 destaca correctamente y mi scrollview se está desplazando!

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;
    }
 39
Author: Jeff,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-13 19:16:36

Intente establecer la propiedad UIScrollView delaysContentTouches a NO.

 26
Author: Vladimir,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-09-04 14:22:14

Solución de Storyboard: Seleccione la vista de desplazamiento, abra el "Inspector de atributos" y desmarque "Retarda los toques de contenido"

introduzca la descripción de la imagen aquí

 1
Author: José,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-01-17 09:54:47

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 esto ScrollViewWithButtons en IB o en código.

 1
Author: Simon Reggiani,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-21 17:16:59

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

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

Mi solución: Dentro del método UIButtons ' tap, donde cargo el nuevo UIViewController y lo presento en la pantalla, use

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

Esto programa la carga del siguiente UIViewController en el siguiente bucle de eventos. Dejando tiempo para que UIButton vuelva a dibujar. El UIButton ahora muestra su estado deprimido antes de cargar el siguiente UIViewController.

 0
Author: Brad Goss,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-04-29 09:01:25

Swift 3:

scrollView.delaysContentTouches = false
 0
Author: Oubaida AlQuraan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-27 14:29:05