将 GestureRecogniser 附加到多个图像视图

Posted

技术标签:

【中文标题】将 GestureRecogniser 附加到多个图像视图【英文标题】:Attach GestureRecogniser to multiple imageviews 【发布时间】:2012-07-04 14:09:58 【问题描述】:

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

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

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

请注意,我不想使用 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];

【问题讨论】:

【参考方案1】:

是的,每个手势识别器一个视图。因此,如果您只想要一个识别器,请将其放在 superview 上,例如:

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,但事实并非如此。另请注意,我使用本地 var 作为识别器,因为没有理由坚持使用它。

更新:

虽然上面的代码可以正常工作,但如果长按没有发生在图像上,自定义长按手势识别器可能会更好(这样如果你有其他在您的视图中发生的手势识别器)。所以:

#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];
                         ];
    

【讨论】:

谢谢,太好了!我需要注意我不想添加手势的图像视图!我猜我可以使用触摸位置来做到这一点。 天啊,我今天才发现这个,我想知道为什么我该死的 UITableViewCell 只适用于最后一个刷过的单元格:P【参考方案2】:

您不能将手势识别器附加到多个对象(如您所见)。您正在做的事情的一种解决方案可能是将 UIImageView 子类化并在该类中设置代码,以便每个视图创建其识别器等。

【讨论】:

【参考方案3】:

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

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

【讨论】:

以上是关于将 GestureRecogniser 附加到多个图像视图的主要内容,如果未能解决你的问题,请参考以下文章

您可以将 Amazon EBS 附加到多个实例吗?

将组件附加到多个键

将多个元素附加到 DOM 的 jquery 会丢失排序顺序

将多个 DataFrame 附加到多个现有的 Excel 工作表

如何将多个 filter() 查询附加到一个变量中

将多个 ebs 卷附加到每个 ec2 实例