ios - El toque de UIButton se retrasa cuando está en UIScrollView
touchescancelled (7)
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)
}
}
Luego puede usar este ScrollViewWithButtons
en IB o en el código.
Estoy teniendo un pequeño problema en mi aplicación.
Básicamente, tengo una serie de UIButtons
agregados como subvistas en un UIScrollView
que es parte de una pluma. Cada vez que toco un botón hay una demora notable antes de que se resalte el botón. Básicamente, tengo que mantenerlo presionado 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
debe determinar si el toque es un desplazamiento o si es un toque destinado a una subvista.
De todos modos, estoy un poco inseguro sobre cómo proceder. Simplemente quiero que el botón aparezca seleccionado tan pronto como lo toco.
Cualquier ayuda es apreciada!
Editar:
He intentado configurar delaysContentTouches
en NO, pero el desplazamiento es casi imposible, ya que la mayoría de mi scrollView está lleno de UIButtons
.
Intente establecer la propiedad UIScrollView delaysContentTouches
en NO.
La solución de Jeff no me funcionó del todo, pero sí una similar: http://charlesharley.com/2013/programming/uibutton-in-uitableviewcell-has-no-highlight-state
Además de anular los touchesShouldCancelInContentView
en su subclase de vista de desplazamiento, aún debe establecer delaysContentTouches
en false
. Por último, debe devolver true
lugar de false
para sus botones. Aquí hay un ejemplo modificado del enlace de arriba. Como sugirieron los comentaristas, comprueba cualquier subclase de UIControl
lugar de UIButton
específicamente para que este comportamiento se aplique a cualquier tipo de control.
C objetivo:
- (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)
}
Ninguna de las soluciones existentes funcionó para mí. Tal vez mi situación sea más singular.
Tengo muchos UIButtons
dentro de un UIScrollView
. Cuando se presiona un UIViewController
se presenta un nuevo UIViewController
al usuario. Si se mantiene presionado un botón el tiempo suficiente, el botón mostrará su estado deprimido. Mi cliente se quejó de que si toca demasiado rápido, no se muestra ningún estado de depresión.
Mi solución: dentro del método de tap de UIButtons
, donde cargue el nuevo UIViewController
y lo presento en la pantalla, lo uso
[self performSelector:@selector(loadNextScreenWithOptions:)
withObject:options
afterDelay:0.]
Esto programa la carga del siguiente UIViewController
en el siguiente ciclo de eventos. Dejando tiempo para que se UIButton
el UIButton
. El UIButton
ahora muestra su estado deprimido antes de cargar el siguiente UIViewController
.
Ok, lo he resuelto subclasificando UIScrollView
y anulando touchesShouldCancelInContentView
¡Ahora mi UIButton
que fue etiquetado como 99 resaltados correctamente y mi vista de desplazamiento está desplazándose!
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;
}
Swift 3:
scrollView.delaysContentTouches = false