hitTest: WithEvent et sous-vues
J'ai 2 points de vue , mais je veux faire 1 vue (presque) plus.
si je place ma tapGesture sur la v1, le robinet geste fonctionne avec un plus gros hit de la zone
mais si je place ma tapGesture sur la v2, il ne fonctionne pas ( en fait, il ne reconnaît pas la tapGesture à tous, même pas à l'intérieur de l'original de limites), même si je boucle mon TestView1 méthode hittest et les points contenus dans l'image.
#import "ViewController.h"
@interface TestView1 : UIView
@end
@implementation TestView1
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGFloat radius = 100.0;
CGRect frame = CGRectMake(0, 0,
self.frame.size.width + radius,
self.frame.size.height + radius);
if (CGRectContainsPoint(frame, point)) {
return self;
}
return nil;
}
@end
@interface TestView2 : UIView
@end
@implementation TestView2
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
CGFloat radius = 100.0;
CGRect frame = CGRectMake(0, 0,
self.frame.size.width + radius,
self.frame.size.height + radius);
if (CGRectContainsPoint(frame, point)) {
return self;
}
return nil;
}
@end
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad
{
[super viewDidLoad];
TestView1 *v1 = [[TestView1 alloc] initWithFrame:CGRectMake(50.f, 50.f, 100.f, 100.f)];
[self.view addSubview:v1];
TestView2 *v2 = [[TestView2 alloc] initWithFrame:CGRectMake(0.f, 0.f, 100.f, 100.f)];
v2.backgroundColor = UIColor.yellowColor;
[v1 addSubview:v2];
UITapGestureRecognizer *gesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
[v2 addGestureRecognizer:gesture];
}
- (void) panGesture:(UIPanGestureRecognizer *)recognizer
{
NSLog(@"tap");
}
@end
source d'informationauteur Andy Jacobs
Vous devez vous connecter pour publier un commentaire.
Vous n'êtes pas traversant le point de vue de la hiérarchie. À partir de la documentation:
Vous avez seulement besoin de mettre en œuvre
pointInside:withEvent:
. Vous ne devriez pas ignorerhitTest:withEvent:
parce que la norme de mise en œuvre appelle votre mise en œuvre depointInside:withEvent:
et faire pour vous tout le travail difficile de la traversée de la hiérarchie.Mettre en œuvre comme ceci:
Maintenant, si vous avez besoin de la vue est à vous. Vous aviez déjà réussi à étendre palpable domaine de la v1, et avec le code ci-dessus, vous pouvez le faire avec la v2 comme une sous-vue de la v1.
Cependant,
TestView1
etTestView2
implémentations sont exactement les mêmes (même dans ton post original), alors pourquoi avez-vous besoin de les avoir séparés? Vous pourriez faire de v1 et v2 les deux instances de la même classe, par exempleTestView
et les instancier comme suit:Votre v2 ne recevront pas les événements tactiles. parce que quand vous cliquez sur la zone autour de votre v1, il retourne
self
dans son- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
ce qui signifie que vous avez déclaré qu'il est "v1", le hit-test de la vue, qui est la destination de tous les événements tactiles.Le bon moyen de développer votre v1 est palpable ares est de mettre en œuvre
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
dans votreTestView1
etTestView2
:Le code ci-dessus signifie que, lorsque vous cliquez sur la zone autour de votre v1, il déclare "Oui, tu m'ont touché. Et je vais vérifier qui peut s'en occuper. C'est peut-être moi, peut-être que c'est l'un de mes sous-vues". Donc du coup le test continue et v1 trouverez ses sous-vue v2 est le haut de la vue v2 est la destination de votre événement click.
Vous pouvez vous demander comment pourrait v1 sais que v2 est l'un. Voici le pseudo-code de révéler l'astuce:
De ces codes n'ont pas pris
userInteractionEnable
alpha
et d'autres choses en compte, pour des raisons de simplicité.Lorsque vous appelez
[super pointInside:point withEvent:event];
dans votreTestView1
's- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
, il demande si le point de chute dans la v2. Si v2 réponse est oui et parce qu'il n'a pas de sous-vues, de sorte que la v2 sera de retour dans son- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
.C'est tout l'histoire.
Aussi loin que je comprends de votre question, vous avez ajouté plus V2 sur le dessus de la V1. donc V2 sera réalisable seulement dans les limites de la V1. Afin que votre geste n'est pas reconnu dans la V2 de la zone supplémentaire.
Vous avez besoin pour mettre en œuvre la méthode:
Et puis:
À partir de la documentation
La façon dont vous le faites est possible, mais difficile de le faire correctement.
Ce que je recommande est d'ajouter la
UITapGestureRecognizer
de leur commune superview et ensuite décider de ce point de vue est le récepteur en fonction appuyez sur emplacement, par exemple,Si les points de vue n'ont pas de commune superview, juste intégrer chacun d'eux dans une plus grande transparence et d'ajouter le module de reconnaissance de cette plus grande vue.