2010-01-13 25 views
10

Mi aplicación tiene dos UIButtons superpuestos. El botón superior puede estar deshabilitado a veces. Sin embargo, en este caso, los eventos táctiles que recibe parecen transmitirse a la vista subyacente, que en mi caso es el otro botón.Impedir que UIButton deshabilitado propague eventos táctiles

Lo que necesito es que el botón superior intercepte todos los toques y evite que lleguen al botón inferior, incluso en estado desactivado (me complacería incluso si su acción designada se invoca en estado desactivado).

Hasta ahora he tratado:

[topButton setUserInteractionEnabled:YES]; 

y

[topButton setExclusiveTouch:YES]; 

aunque este último caso es probablemente indeseable ya que todavía necesito el botón inferior responder a eventos si es la primera vista hace clic. De cualquier manera ninguno de ellos funciona.

Respuesta

1

crear una subclase del botón, y luego anular estos métodos para que el botón se pondrá al día los acontecimientos, pero ignorarlos si alguna propiedad del botón se establece en NO:

touchesBegan:withEvent: 
touchesCancelled:withEvent: 
touchesEnded:withEvent: 
touchesMoved:withEvent: 

Éstos son los métodos de UIResponder.

Pídales que simplemente llamen a su [super ...] método si desea que se maneje el evento, de lo contrario simplemente no lo llame y regrese si desea que los eventos "coman".

Véase también en este caso es necesario: Observing pinch multi-touch gestures in a UITableView

+0

Parece que estos métodos no se invocan cuando el botón está deshabilitado. –

+0

Sí, eso es lo que pensé (por eso dije "alguna propiedad") y es por eso que puede necesitar usar el segundo método o hacer algo diferente a desactivar el botón como simular que está deshabilitado de alguna manera. El segundo método probablemente sea un problema ya que la aplicación UIA (que llama a sendEvent en la ventana) probablemente sea lo que está ignorando los UIControls deshabilitados. – Nimrod

2

Lo que hice es colocar UIImageView del mismo tamaño con UIButton justo debajo de la UIButton. Luego, aunque deshabilite UIButton, los eventos táctiles no propagan UIImageView.

+0

Esta es en realidad la solución más simple y rápida – codingFriend1

13

he añadido el siguiente método para supervista del botón deshabilitado:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    if (!self.watchButton.enabled && 
     [self.watchButton pointInside:[self convertPoint:point toView:self.watchButton] 
          withEvent:nil]) { 
     return nil; 
    } 
    return [super hitTest:point withEvent:event]; 
} 

Esto funciona bien con células UITableView.

1

Me las arreglé para hacer que esto funcione como lo necesitaba con una versión ligeramente modificada de la respuesta de @kolyuchiy anterior. Anulé el método hitTest:withEvent: en mi subclase UIButton, devolviendo self cuando está deshabilitado y el punto está dentro del marco de la vista para que se consuma el toque, pero no se invoca el manejo de eventos del botón.

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    if (!self.enabled && [self pointInside:[self convertPoint:point toView:self] withEvent:event]) 
    { 
     return self; 
    } 
    return [super hitTest:point withEvent:event]; 
} 
2

Después de probar @kolyuchiy (que requiere modificar el comportamiento UIButton fuera de su alcance) y Patrick @-Lynch (que no funcionó para mí) soluciones vinieron con una más elegante, que se aplica a UIButton subclase :

private static let dummyView: UIView = { 
    let view = UIView(frame: .zero) 
    view.userInteractionEnabled = true 
    return view 
}() 

public override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { 
    if !enabled && pointInside(point, withEvent: event) { 
     return self.dynamicType.dummyView 
    } 
    return super.hitTest(point, withEvent: event) 
} 
+1

Voto ascendente para view.userInteractionEnabled = true. – iwill

Cuestiones relacionadas