248
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)];
[self.view1 addGestureRecognizer:tapGesture];
[self.view2 addGestureRecognizer:tapGesture];
[tapGesture release];

在上面的代码中,只有点击view2被识别。如果我注释掉第三行,则view1可以识别点击。如果我是对的并且您只能使用一次手势识别器,我不确定这是一个错误还是它只需要更多文档。

4

12 回答 12

355

AUIGestureRecognizer将与单个视图一起使用。我同意文档参差不齐。UIGestureRecognizer有一个单一的view属性会泄露它:

看法

手势识别器附加到的视图。(只读)

@property(nonatomic, readonly) UIView *view

讨论 您使用 addGestureRecognizer: 方法将手势识别器附加(或添加)到 UIView 对象。

于 2011-04-06T14:07:20.663 回答
49

我通过使用以下解决了它。

for (UIButton *aButton in myButtons) {

            UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPress:)];
            longPress.minimumPressDuration=1.0;
            [aButton addGestureRecognizer:longPress];
            [longPress release];

}

然后在我的 handleLongPress 方法中,我只设置一个 UIButton 等于手势识别器的视图,并根据该按钮分支我所做的事情

- (void)handleLongPress:(UILongPressGestureRecognizer*)gesture {
    if ( gesture.state == UIGestureRecognizerStateEnded ) {
        UIButton *whichButton=(UIButton *)[gesture view];
        selectedButton=(UIButton *)[gesture view];
    ....
}
于 2011-10-25T01:59:11.393 回答
18

对于 Swift 3,以防万一有人需要:基于上面的 Bhavik Rathod 答案。

 func setGestureRecognizer() -> UIPanGestureRecognizer {

        var panRecognizer = UIPanGestureRecognizer()

        panRecognizer = UIPanGestureRecognizer (target: self, action: #selector(pan(panGesture:)))
        panRecognizer.minimumNumberOfTouches = 1
        panRecognizer.maximumNumberOfTouches = 1
        return panRecognizer
    }

        ///set the recognize in multiple views
        view1.addGestureRecognizer(setGestureRecognizer())
        view2.addGestureRecognizer(setGestureRecognizer())
于 2016-11-03T15:33:46.567 回答
12

我们可以做这样的事情,简单易行

1)在您的控制器中创建如下函数(此函数将返回 GestureRecognizer)

-(UITapGestureRecognizer*)setRecognizer{
     UITapGestureRecognizer *gestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(openProfile)];
     [gestureRecognizer setNumberOfTapsRequired:1];
     return gestureRecognizer;
}

2) 现在在多个视图中设置此识别器

[self.view1 addGestureRecognizer:[self setRecognizer]]; 
[self.view2 addGestureRecognizer:[self setRecognizer]];
于 2016-09-13T11:04:18.703 回答
10

不,您不应将手势识别器附加到多个视图。

Apple 文档中有这样的明确信息:

手势识别器附加到视图

每个手势识别器都与一个视图相关联。相比之下,一个视图可以有多个手势识别器,因为一个视图可能会响应许多不同的手势。要让手势识别器识别特定视图中发生的触摸,您必须将手势识别器附加到该视图。

iOS 事件处理指南 - 手势识别器Apple Developer Library

虽然正如其他人提到的那样,它们在某些情况下可能会起作用,但这显然违反了文档,并且可能在任何未来的 iOS 版本中发生变化。

您可以做的是将单独的手势识别器添加到您要监视的视图中,它们可以共享一个共同的操作。

于 2015-07-07T16:56:20.167 回答
4

好吧,如果有人不想为kwalker上面回答的多个按钮添加手势视图而编写代码,并且想通过 Interface Builder 来实现,这可能会对您有所帮助。

1)您可以从对象库中添加长按手势识别器,就像添加其他对象(如 UIButtons 和 UILabels)一样。

在此处输入图像描述 最初我最终使用的是我只拿了一个

2) 将引用出口设置到UIButton文件所有者并发送操作。

在此处输入图像描述

注意:如果您有多个 UIButton 或任何其他对象,则每个对象都需要单独的手势识别器。有关更多详细信息,请参阅我的这个问题。在长按手势识别器上获取错误的 UIButton 标签

于 2013-03-20T14:20:24.107 回答
3

如果你有固定的观点,我建议你做这样的事情

[self.view1 addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)]];
[self.view2 addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapTapTap:)]];

这种方式将减少多个不同的无用变量

于 2017-11-01T03:32:14.150 回答
3

您可以在视图上创建通用扩展以轻松添加手势识别器。这只是一个例子,但它可能看起来像这样

extension UIView {

    func setGestureRecognizer<Gesture: UIGestureRecognizer>(of type: Gesture.Type, target: Any, actionSelector: Selector, swipeDirection: UISwipeGestureRecognizer.Direction? = nil, numOfTaps: Int = 1) {
    let getRecognizer = type.init(target: target, action: actionSelector)

    switch getRecognizer {
    case let swipeGesture as UISwipeGestureRecognizer:
        guard let direction = swipeDirection else { return }
        swipeGesture.direction = direction
        self.addGestureRecognizer(swipeGesture)
    case let tapGesture as UITapGestureRecognizer:
        tapGesture.numberOfTapsRequired = numOfTaps
        self.addGestureRecognizer(tapGesture)
    default:
        self.addGestureRecognizer(getRecognizer)
    }
  }

}

要在视图上添加 2 次点击识别器,您只需调用:

let actionSelector = #selector(actionToExecute)
view.setGestureRecognizer(of: UITapGestureRecognizer.self, target: self, actionSelector: actionSelector, numOfTaps: 2)

您还可以轻松添加滑动识别器

view.setGestureRecognizer(of: UISwipeGestureRecognizer.self, target: self, actionSelector: actionSelector, swipeDirection: .down)

等等。请记住,目标必须链接到选择器。

于 2019-08-13T15:16:34.730 回答
2

<UIScrollViewDelegate>用' '覆盖类

并在 .m 类中使用此方法:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
    return YES;
}

此方法将帮助您在单个视图上启用多次滑动。

于 2015-12-06T07:55:10.237 回答
2

每次添加指向相同功能的手势识别器时,重新编写(重新创建)您的 GestureRecognize 怎么样。在以下情况下,它可以工作。我正在使用 IBOutletCollection

斯威夫特 2:

@IBOutlet var topicView: [UIView]!

override func viewDidLoad() {
        for view in self.topicView as [UIView] {
        view.addGestureRecognizer(UITapGestureRecognizer(target: self, action: "viewClicked:"))
    }
}

func viewClicked(recognizer: UITapGestureRecognizer) {
    print("tap")
}
于 2016-03-21T19:25:20.750 回答
1

我知道这是一篇旧帖子,但我想出了类似的东西,希望它对其他人有用。我只是将我的 imageViews 存储在一个数组中,并将其分配给一个函数中的同一个手势识别器,以设置每个图像视图。

在我看来DidLoad():

imageViewList = [imageView, imageView2, imageView3]
setupImageViews(imageViews: imageViewList)

设置图像视图的功能:

func setupImageViews(imageViews: [UIImageView]) {
    
    for imageView in imageViews {
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
        imageView.isUserInteractionEnabled = true
        imageView.addGestureRecognizer(tapGestureRecognizer)
        
        //set up image to be displayed with the right aspect
        imageView.autoresizingMask = [.flexibleWidth, .flexibleHeight, .flexibleBottomMargin, .flexibleRightMargin, .flexibleLeftMargin, .flexibleTopMargin]
        imageView.contentMode = .scaleAspectFit // OR .scaleAspectFill
        imageView.clipsToBounds = true
    }
}

在动作选择器 imageTapped() 中,您可以为所点击的任何图像视图设置相应的代码。

@objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
{
    switch tapGestureRecognizer.view {
    case imageView:
        print("tapped Image View 1") //add your actions here
    case imageView2:
        print("tapped Image View 2") //add your actions here
    case imageView3:
        print("tapped Image View 3") //add your actions here
    default:
        print("Tap not detected")
    }
    _ = tapGestureRecognizer.view as! UIImageView
    //additional code...
}
于 2020-08-24T12:57:11.267 回答
-7

您可以使用此代码执行此操作,我的视图是 xib 中的图像视图。

- (void)viewDidLoad
{
    firstIV.tag = 501;
    secondIV.tag = 502;
    thirdIV.tag = 503;
    forthIV.tag = 504;

    [self addTapGesturetoImageView: firstIV];
    [self addTapGesturetoImageView: secondIV];
    [self addTapGesturetoImageView: thirdIV];
    [self addTapGesturetoImageView: forthIV];
}

-(void)addTapGesturetoImageView:(UIImageView*)iv
{
    iv.userInteractionEnabled = YES;
    UITapGestureRecognizer * textfielBGIVTapGasture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(textfielBGIVTapped:)];
    textfielBGIVTapGasture.numberOfTapsRequired = 1;
    [iv addGestureRecognizer:textfielBGIVTapGasture];
}

- (void)textfielBGIVTapped:(UITapGestureRecognizer *)recognizer {
    int tag = recognizer.view.tag-500;
    switch (tag) {
        case 1:
        {
            //firstIV tapped;
            break;
        }
        case 2:
        {
            //secondIV tapped;
            break;
        }
        case 3:
        {
            //thirdIV tapped;
            break;
        }
        case 4:
        {
            //forthIV tapped;
            break;
        }
        default: {
            break;
        }
    }
}
于 2013-09-20T10:36:24.710 回答