web-dev-qa-db-fra.com

Détecter si certains UIView ont été touchés parmi d'autres UIViews

J'ai 3 UIViews, superposés sur un grand uiview. Je veux savoir si l'utilisateur touche le premier et ne se soucie pas des autres. J'aurai deux boutons dans le deuxième UIView et un UITable dans le troisième UIView. 

Le problème est que j'active userInteractionEngabled sur la première vue et que cela fonctionne, mais toutes les autres vues répondent de la même manière même si je l'éteins Si je désactive userInteractionEnabled sur self.view, aucun d’eux ne répond. Je ne peux pas non plus détecter quelle vue a été touchée dans la méthode de délégué touchesBegan.

Mon code:

UIView *aView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 320, 150)];
aView = userInteractionEnabled = YES;
[self.view addSubview:aView];

UIView *bView = [[UIView alloc] initWithFrame:CGRectMake(0, 150, 320, 50)];
bView.userInteractionEnabled = NO;
[self.view addSubview:bView];

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
//This gets called for a touch anywhere
}
30
Rudiger

Pour vérifier si certaines vues d'une autre vue ont été touchées, vous pouvez utiliser hitTest. 

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

Dans votre implémentation personnalisée de touchesBegan, vérifiez chaque touche par jeu de touches. Le point pour la méthode hitTest peut être obtenu en utilisant 

- (CGPoint)locationInView:(UIView *)view;

méthode, où la vue est votre superView (celle qui contient d’autres vues). 

EDIT: Voici une implémentation rapide et personnalisée:

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 
    CGPoint locationPoint = [[touches anyObject] locationInView:self];
    UIView* viewYouWishToObtain = [self hitTest:locationPoint withEvent:event];
}

J'espère que cela a été utile, Paul

62
Pawel

Dans mon cas, l'UIView que je voulais trouver n'était pas renvoyé par le hotTest. Mais le code suivant a mieux fonctionné:

    CGPoint locationPoint = [[touches anyObject] locationInView:self.view];
    CGPoint viewPoint = [myImage convertPoint:locationPoint fromView:self.view];
    if ([myImage pointInside:viewPoint withEvent:event]) {
       do something
    }
27
rgadbois

Cela peut aussi être fait de la manière suivante.

Recherchez d'abord l'emplacement du contact dans la vue qui vous intéresse:

CGPoint location = [touches.anyObject locationInView:viewYouCareAbout];

Ensuite, voyez si le point est dans les limites de la vue:

BOOL withinBounds = CGRectContainsPoint(viewYouCareAbout.bounds, location);

Ensuite, si c'est dans les limites, effectuez votre action.

Cela peut être fait avec une instruction, qui peut par exemple être utilisée directement dans une instruction if:

CGRectContainsPoint(viewYouCareAbout.bounds, [touches.anyObject locationInView:viewYouCareAbout])
13
Ben Baron

Code rapide:

 override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if let touch = touches.first {
            if touch.view == self.view {
                self.hideInView()
            } else {
                return
            }

        }
    }
12
Karthi Keyan

Dans touchesBegan , vérifiez que la vue touchée est celle que vous voulez, a résolu le problème pour moi lorsque j’essayais d’identifier si l’utilisateur touchait un ImageView spécifique.

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    if ([touch view] ==  imageView ) {
        ... your code to handle the touch
    }
    ...

Si vous ajustez le contenu pour les diamètres de la vue, veillez à modifier la taille de la vue en conséquence, sinon l'événement tactile sera reconnu, même dans la zone où se trouve le contenu de la vue. Dans mon cas, lorsque j'ai essayé de conserver la proportion d'image avec UIViewContentModeScaleAspectFit , bien que l'image ait été ajustée comme il convient dans les zones tactiles "espaces blancs", l'événement tactile a également été saisi.

8
Pichirichi

Ma version de Swift pour vérifier que le contact a eu lieu dans infoView:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    guard let touch = touches.first, infoView.bounds.contains(touch.location(in: infoView))  else { return }
    print("touchesBegan") // Replace by your own code
} // touchesBegan
3
KerCodex

Cela a fonctionné pour moi:

func respondToGesture(gesture: UIGestureRecognizer) {
    let containsPoint = CGRectContainsPoint(targetView.bounds, gesture.locationInView(targetView))
}
0
Andy