2010-01-13 1 views
10

La mia applicazione ha due UIButton sovrapposti. Il pulsante in alto potrebbe essere disabilitato a volte. Tuttavia, in questo caso, qualsiasi evento di tocco ricevuto sembra essere passato alla vista sottostante, che nel mio caso è l'altro pulsante.Impedisci UIButton disabilitato dalla propagazione di eventi di tocco

Quello che mi serve è il pulsante in alto che intercetta tutti i tocchi e impedisce loro di raggiungere il pulsante in basso, anche in stato disabilitato (sarei felice anche se l'azione designata è invocata nello stato disabilitato).

Finora ho provato:

[topButton setUserInteractionEnabled:YES]; 

e

[topButton setExclusiveTouch:YES]; 

anche se quest'ultimo caso è probabilmente indesiderabile in quanto ho ancora bisogno il pulsante in basso rispondere agli eventi se è la prima vista cliccato. In entrambi i casi nessuno di loro funziona.

risposta

1

creare una sottoclasse del pulsante, quindi sovrascrivere questi metodi in modo che il pulsante prenderà eventi, ma ignorarli se alcune proprietà del pulsante è impostata su NO:

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

Questi sono metodi di UIResponder.

Invitali a chiamare il loro metodo [super ...] se vuoi che l'evento venga gestito, altrimenti non chiamarlo e torna se vuoi che gli eventi siano "mangiati".

anche vedere questo nel caso in cui sia necessario: Observing pinch multi-touch gestures in a UITableView

+0

Sembra che questi metodi non vengano chiamati quando il pulsante è disabilitato. –

+0

Sì, questo è quello che ho capito (che è il motivo per cui ho detto "alcune proprietà") che è il motivo per cui potrebbe essere necessario utilizzare il secondo metodo, o fare qualcosa di diverso da disabilitare il pulsante come simulare di essere disabilitato in qualche modo. Il secondo metodo probabilmente sarà un problema dal momento che l'applicazione UIA (che chiama sendEvent nella finestra) probabilmente è ciò che sta ignorando UIControls disabilitato. – Nimrod

2

Quello che ho fatto sta mettendo UIImageView della stessa dimensione con UIButton appena sotto l'UIButton. Quindi, anche se si disabilita UIButton, gli eventi di tocco non propagano UIImageView.

+0

Questa è in realtà la soluzione più semplice e veloce – codingFriend1

13

ho aggiunto il seguente metodo per superview del pulsante disabilitato:

- (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]; 
} 

Questo metodo funziona bene con le cellule UITableView.

1

Sono riuscito a farlo funzionare come avevo bisogno con una versione leggermente modificata della risposta di @kolyuchiy sopra. Ho annullato il metodo hitTest:withEvent: nella sottoclasse UIButton, restituendo self quando disabilitato e il punto si trova all'interno della cornice della vista in modo che venga utilizzato il tocco, ma la gestione degli eventi del pulsante non viene richiamata.

- (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

Dopo aver provato @kolyuchiy (che richiede di modificare UIButton comportamento al di fuori del suo ambito di applicazione) e @ patrick-Lynch (che proprio non ha funzionato per me) soluzioni venuto con uno più elegante, che si applica a UIButton sottoclasse :

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 per view.userInteractionEnabled = true. – iwill