2010-01-13 6 views
10

Mon application comporte deux UIButtons qui se chevauchent. Le bouton du haut peut être désactivé parfois. Cependant, dans ce cas, tous les événements tactiles qu'il reçoit semblent être transmis à la vue sous-jacente, ce qui dans mon cas est l'autre bouton. Ce dont j'ai besoin, c'est que le bouton du haut intercepte toutes les touches et les empêche d'atteindre le bouton du bas, même en état désactivé (je serais heureux même si l'action désignée est invoquée dans l'état désactivé).Empêcher UIButton désactivé de propager des événements tactiles

Jusqu'à présent, j'ai essayé:

[topButton setUserInteractionEnabled:YES]; 

et

[topButton setExclusiveTouch:YES]; 

si le dernier cas est probablement indésirable, car je dois encore le bouton du bas répondre à des événements si elle est la première vue cliqué. De toute façon, aucun d'entre eux ne fonctionne.

Répondre

1

Créer une sous-classe du bouton, puis remplacer ces méthodes de sorte que le bouton attraper les événements mais les ignorer si une propriété du bouton est réglé sur NO:

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

Ce sont des méthodes de UIResponder. Demandez-leur simplement d'appeler leur méthode [super ...] si vous voulez gérer l'événement, sinon ne l'appelez pas et revenez si vous voulez que les événements soient «mangés».

Voir aussi ce dans le cas où il est nécessaire: Observing pinch multi-touch gestures in a UITableView

+0

Apparemment, ces méthodes ne sont pas appelées du tout lorsque le bouton est désactivé. –

+0

Oui, c'est ce que je pensais (c'est pourquoi j'ai dit "une propriété"), c'est pourquoi vous devrez peut-être utiliser la seconde méthode, ou faire autre chose que désactiver le bouton comme simuler être désactivé en quelque sorte. La deuxième méthode sera probablement pénible car UIApplication (qui appelle sendEvent dans la fenêtre) est probablement ce qui ignore les UIControls désactivés. – Nimrod

2

Ce que je l'ai fait est mise UIImageView de même taille avec UIButton juste sous la UIButton. Ensuite, même si vous désactivez UIButton, les événements tactiles ne propagent pas UIImageView.

+0

C'est en fait la solution la plus simple et la plus rapide. – codingFriend1

13

I a ajouté la méthode suivante pour superview du bouton désactivé:

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

Cela fonctionne bien avec des cellules uitableview.

1

J'ai réussi à obtenir ce travail comme j'avais besoin avec une version légèrement modifiée de la réponse @kolyuchiy ci-dessus. J'ai outrepassé la méthode hitTest:withEvent: dans ma sous-classe UIButton, renvoyant self lorsqu'elle est désactivée et que le point est dans l'image de la vue afin que le toucher soit consommé, mais la gestion des événements du bouton n'est pas appelée.

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

Après avoir essayé @kolyuchiy (ce qui nécessite de modifier le comportement UIButton en dehors de son champ d'application) et @ patrick-lynchage (ce qui n'a pas fonctionné pour moi) des solutions était fourni avec plus élégante, qui applique à la sous-classe UIButton :

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

Votez pour view.userInteractionEnabled = true. – iwill

Questions connexes