78 votes

Comment ignorer les événements tactiles et les transmettre aux objets UIControl d'une autre sous-vue?

J'ai un custom UIViewController dont UIView prend un coin de l'écran, mais la plupart de celui-ci est transparent sauf pour les parties qui ont des boutons et des trucs sur elle. En raison de la disposition des objets sur ce point de vue, le point de vue de l'image peuvent recouvrir des boutons en dessous. Je veux être en mesure d'ignorer tout touche à ce point de vue s'ils ne sont pas toucher quoi que ce soit d'important sur lui, mais il me semble seulement être en mesure de passer le long de réels événements tactiles (touchesEnded/nextResponder genre de trucs). Si j'ai un UIButton ou quelque chose comme ça qui ne marche pas utiliser touchesEnded, comment puis-je passer l'événement tactile le long de qui?

Je ne peux pas juste manuellement figure bouton sélecteur pour appeler, parce que cette coutume ViewController peut être utilisé sur de nombreux points de vue différents. J'ai essentiellement besoin d'un moyen d'appeler ce:

[self.nextResponder touchesEnded:touches withEvent:event];

sur UIControl types ainsi.

139voto

Stuart Points 8578

Probablement la meilleure façon de le faire est de remplacer hitTest:withEvent: dans la vue que vous souhaitez ignorer touche. Selon la complexité de votre point de vue de la hiérarchie, il ya un couple de façons simples de le faire.

Si vous avez une référence à la vue sous le point de vue de l'ignorer:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *hitView = [super hitTest:point withEvent:event];

    // If the hitView is THIS view, return the view that you want to receive the touch instead:
    if (hitView == self) {
        return otherView;
    }
    // Else return the hitView (as it could be one of this view's buttons):
    return hitView;
}

Si vous n'avez pas de référence à la vue:

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *hitView = [super hitTest:point withEvent:event];

    // If the hitView is THIS view, return nil and allow hitTest:withEvent: to
    // continue traversing the hierarchy to find the underlying view.
    if (hitView == self) {
        return nil;
    }
    // Else return the hitView (as it could be one of this view's buttons):
    return hitView;
}

Je recommande la première approche est la plus robuste (si c'est possible d'obtenir une référence pour la vision sous-jacente).

MODIFIER

Si vous créez votre "ignorer" vue par programmation, créer votre point de vue sous-classe (je l'ai appelé, il MyPassthroughView) et la définir comme le point de vue du contrôleur de vue en loadView:

- (void)loadView
{
    CGRect rootFrame = //...
    MyPassthroughView *passthroughView = [[MyPassthroughView alloc] initWithFrame:rootFrame];
    self.view = passthroughView;
    // ...
    // Additional setup...
    // ...

    [passthroughView release];  // (If not using ARC...)
}

8voto

EricS Points 5072

Je n'ai pas trouvé un bon moyen de transmettre des événements UITouch entre des objets. Ce qui fonctionne généralement mieux est d’appliquer hitTest et de renvoyer nil si le point n’est pas dans la vue que vous voulez gérer:

 - (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X