将手势识别器附加到多个图像视图

问题描述:

将当前手势识别器附加到多个图像视图时,我今天遇到了一些奇怪的事情。它只附加到最后一个,换句话说,它只能附加到一个视图!将手势识别器附加到多个图像视图

我不得不创建多个手势识别器来满足我的要求。

以下是我所做的。我做得对吗?这是将识别器附加到多个图像视图的唯一方法吗?

请注意,我不想使用UITableView或UIVIew并将其中的所有图像,并将手势识别器仅附加到UITableView或UIVIew。我有所有图像分散,我必须检测哪个图像被拖动。谢谢。

[imgView1 setUserInteractionEnabled:YES]; 
[imgView1 setMultipleTouchEnabled:YES]; 

[imgView2 setUserInteractionEnabled:YES]; 
[imgView2 setMultipleTouchEnabled:YES]; 

[imgView3 setUserInteractionEnabled:YES]; 
[imgView3 setMultipleTouchEnabled:YES]; 

[imgView4 setUserInteractionEnabled:YES]; 
[imgView4 setMultipleTouchEnabled:YES]; 

[imgView5 setUserInteractionEnabled:YES]; 
[imgView5 setMultipleTouchEnabled:YES]; 

[imgView6 setUserInteractionEnabled:YES]; 
[imgView6 setMultipleTouchEnabled:YES]; 


//Attach gesture recognizer to each imagviews 
gestureRecognizer1 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(gestureHandler:)]; 
gestureRecognizer1.delegate = self; 

gestureRecognizer2 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(gestureHandler:)]; 
gestureRecognizer2.delegate = self; 

gestureRecognizer3 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(gestureHandler:)]; 
gestureRecognizer3.delegate = self; 

gestureRecognizer4 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(gestureHandler:)]; 
gestureRecognizer4.delegate = self; 

gestureRecognizer5 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(gestureHandler:)]; 
gestureRecognizer5.delegate = self; 

gestureRecognizer6 = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(gestureHandler:)]; 
gestureRecognizer6.delegate = self; 

[imgView1 addGestureRecognizer:gestureRecognizer1]; 
[imgView2 addGestureRecognizer:gestureRecognizer2]; 
[imgView3 addGestureRecognizer:gestureRecognizer3]; 
[imgView4 addGestureRecognizer:gestureRecognizer4]; 
[imgView5 addGestureRecognizer:gestureRecognizer5]; 
[imgView6 addGestureRecognizer:gestureRecognizer6]; 

是的,每个手势识别器有一个视图。所以,如果你只想要一个识别器,把它放在上海华,例如:

UILongPressGestureRecognizer *gestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(gestureHandler:)]; 
[self.view addGestureRecognizer:gestureRecognizer]; 

,然后在您的处理程序,您可以:

- (void)handleLongPress:(UILongPressGestureRecognizer *)sender 
{ 
    CGPoint location = [sender locationInView:self.view]; 

    if (sender.state == UIGestureRecognizerStateBegan) 
    { 
     for (UIView *view in self.view.subviews) 
     { 
      if ([view isKindOfClass:[UIImageView class]] && CGRectContainsPoint(view.frame, location)) 
      { 
       UIImageView *image = (UIImageView *) view; 

       // ok, now you know which image you received your long press for 
       // do whatever you wanted on it at this point 

       return; 
      } 
     } 
    } 
} 

顺便说一句,如果你这样做,你不需要担心在图像上启用用户交互。

最后,除非您要符合UIGestureRecognizerDelegate,否则不需要担心指定您的手势识别器的代表。另外请注意,我为识别器使用了一个本地变量,因为没有理由挂在它上面。

更新:

虽然上面的代码工作正常,或许更重要的是一个自定义的长按手势识别,如果长按并没有发生过的图像(这样它更是会失败如果您在视图中发现其他手势识别器,可能会发挥出色)。所以:

#import <UIKit/UIGestureRecognizerSubclass.h> 

@interface ImageLongPressGestureRecognizer : UILongPressGestureRecognizer 
@property (nonatomic, weak) UIImageView *imageview; 
@end 

@implementation ImageLongPressGestureRecognizer 

@synthesize imageview = _imageview; 

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 
    self.imageview = nil; 

    [super touchesBegan:touches withEvent:event]; 

    CGPoint location = [self locationInView:self.view]; 

    for (UIView *view in self.view.subviews) 
    { 
     if ([view isKindOfClass:[UIImageView class]] && CGRectContainsPoint(view.frame, location)) 
     { 
      self.imageview = (UIImageView *)view; 
      return; 
     } 
    } 

    self.state = UIGestureRecognizerStateFailed; 
} 

@end 

然后相应地创建您的手势识别,使用这个新的子类:

ImageLongPressGestureRecognizer *gestureRecognizer = [[ImageLongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)]; 
[self.view addGestureRecognizer:gestureRecognizer]; 

然后,作为这个子类的一个不错的效益,你的主要手势识别被简化,即:

- (void)handleLongPress:(ImageLongPressGestureRecognizer *)sender 
{ 
    if (sender.state == UIGestureRecognizerStateBegan) 
    { 
     // you can now do whatever you want with sender.imageview, e.g. this makes it blink for you: 

     [UIView animateWithDuration:0.5 
         animations:^{ 
          sender.imageview.alpha = 0.0; 
         } completion:^(BOOL finished){ 
          [UIView animateWithDuration:0.5 
               animations:^{ 
                sender.imageview.alpha = 1.0; 
               } 
               completion:nil]; 
         }]; 
    } 
} 
+0

非常感谢!我需要关心我不想添加手势的图像浏览!我可以使用触摸位置来做到这一点。 – applefreak

+0

Omg,我今天才发现这个,我想知道为什么我的darn UITableViewCell只能用于最后一个被刷过的单元格:P – Zhang

您无法将手势识别器附加到多个对象(如您发现的那样)。你正在做的一个解决方案可能是UIImageView的子类,并在该类中设置代码,以便每个视图创建其识别器等。

+0

谢谢。创建子类是一个好主意。 – applefreak

我想,首先,你应该制作一个视图数组和识别器数组(可变数组,如果需要的话),然后填充它。它将帮助您使用循环来避免代码重复。

至于多视图与一个识别器 - 不,这是不可能的,answered here