您可以将 UIGestureRecognizer 附加到多个视图吗?

发布于 2024-10-13 04:02:13 字数 389 浏览 9 评论 0原文

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

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

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

In the above code only taps on view2 are recognized. If I comment out the third line then taps on view1 are recognized. If I'm right and you can only use a gesture recognizer once, I'm not sure if this is a bug or it just needs some more documentation.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(13

傲世九天 2024-10-20 04:02:13

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

查看

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

@property(非原子,只读) UIView *view

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

A UIGestureRecognizer is to be used with a single view. I agree the documentation is spotty. That UIGestureRecognizer has a single view property gives it away:

view

The view the gesture recognizer is attached to. (read-only)

@property(nonatomic, readonly) UIView *view

Discussion You attach (or add) a gesture recognizer to a UIView object
using the addGestureRecognizer:
method.

虫児飞 2024-10-20 04:02:13

我通过使用下面的方法解决了这个问题。

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];
    ....
}

I got around it by using the below.

for (UIButton *aButton in myButtons) {

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

}

Then in my handleLongPress method I just set a UIButton equal to the view of the gesture recognizer and branch what I do based upon that button

- (void)handleLongPress:(UILongPressGestureRecognizer*)gesture {
    if ( gesture.state == UIGestureRecognizerStateEnded ) {
        UIButton *whichButton=(UIButton *)[gesture view];
        selectedButton=(UIButton *)[gesture view];
    ....
}
向日葵 2024-10-20 04:02:13

对于 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())

For Swift 3 in case anyone requires this:
Based on Bhavik Rathod Answer above.

 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())
以为你会在 2024-10-20 04:02:13

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

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

手势识别器附加到视图

每个手势识别器都与一个视图相关联。相比之下,一个
视图可以有多个手势识别器,因为单个视图
可能会对许多不同的手势做出反应。对于手势识别器来说
识别发生在特定视图中的触摸,您必须附加
该视图的手势识别器。

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

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

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

No you should not attach gesture recognizers to more than one view.

There is this explicit information in the Apple documentation:

Gesture Recognizers Are Attached to a View

Every gesture recognizer is associated with one view. By contrast, a
view can have multiple gesture recognizers, because a single view
might respond to many different gestures. For a gesture recognizer to
recognize touches that occur in a particular view, you must attach the
gesture recognizer to that view.

Event Handling Guide for iOS - Gesture Recognizers Apple Developer Library

While as others mention they might work in some cases it is clearly against the documentation and could change in any future iOS version.

What you can do is add separate gesture recognisers to the views you want to monitor and they can share a common action.

写给空气的情书 2024-10-20 04:02:13

我们可以做这样的事情,它很简单

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

We can do something Like this, it's easy and simple

1) create function as below in your controller (this function will return GestureRecognizer)

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

2) now set this recognizer in multiple views

[self.view1 addGestureRecognizer:[self setRecognizer]]; 
[self.view2 addGestureRecognizer:[self setRecognizer]];
百善笑为先 2024-10-20 04:02:13

好吧,如果有人不想编写为多个按钮添加手势视图的代码,例如 kwalker 已经在上面回答了,并且想要这样做通过 Interface Builder 这可能会帮助你。

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

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

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

在此处输入图像描述

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

Well if someone does not want to code for adding gesture view for multiple buttons like kwalker has answered above, and want to do it via Interface Builder this may help you.

1) You can add Long Press gesture Recognizer from Object Library like you add other objects like UIButtons and UILabels.

enter image description here
Initially what I ended up using was I took only one

2) Set referencing outlets to UIButton and sent actions with File's Owner.

enter image description here

Note: If you have multiple UIButton or any other object you will need separate gesture recognizer for each of them. For more details please refer to this question of mine.Getting wrong UIButton tag on Long press gesture recognizer

唱一曲作罢 2024-10-20 04:02:13

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

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

,这样会减少多个不同的无用变量

if you have fixed view I suggest you doing something like this

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

that way will reduce multiple different useless variable

∞梦里开花 2024-10-20 04:02:13

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

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)

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

You could create a generic extension on view to add gesture recognizers easily.
This is just an example but it could look like this

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)
    }
  }

}

To add a 2 tap recognizer on a view you would just call:

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

You could also easily add a swipe recognizer

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

and so on.
Just remember that the target must be linked to the selector.

小梨窩很甜 2024-10-20 04:02:13

通过 '' 覆盖类

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

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

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

Override class by '<UIScrollViewDelegate>'

And use this method in .m class:

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

This method will help you to enable multiple swipe on a single view..

∝单色的世界 2024-10-20 04:02:13

每次添加指向同一函数的手势识别器时,重新编写(重新创建)您的 GestureRecognize 怎么样?
在下面的情况下它有效。我正在使用 IBOutletCollection

Swift 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")
}

What about re write (recreate) your GestureRecognize every time that you add a gesture recognizer pointing to the same func.
In below case it works. I am using IBOutletCollection

Swift 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")
}
ゃ懵逼小萝莉 2024-10-20 04:02:13

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

在我的 viewDidLoad():

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...
}

I know this is an old post but I figured something similar and hopefully it's useful someone else. I simply stored my imageViews in an array and assigned it to to the same gesture recognizer in a function to set up each image view.

In my viewDidLoad():

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

Function to setup image views:

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
    }
}

And in the action selector imageTapped(), you can have corresponding code for whichever image view tapped.

@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...
}
丶情人眼里出诗心の 2024-10-20 04:02:13

要在 Swift 中向多个视图添加点击手势,您可以使用循环迭代视图并向每个视图添加手势识别器。这是一个例子:

let views = [view1, view2, view3, view4]
        views.forEach { view in
            let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
            view.isUserInteractionEnabled = true
            view.addGestureRecognizer(tap)
        }
    }
    
    @objc func handleTap(_ sender: UITapGestureRecognizer? = nil) {
        switch sender?.view {
        case view1:
            //do something
        case view2:
            //do something
        default:
            break
        }
    }

To add a tap gesture to multiple views in Swift, you can use a loop to iterate through the views and add the gesture recognizer to each one. Here's an example:

let views = [view1, view2, view3, view4]
        views.forEach { view in
            let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
            view.isUserInteractionEnabled = true
            view.addGestureRecognizer(tap)
        }
    }
    
    @objc func handleTap(_ sender: UITapGestureRecognizer? = nil) {
        switch sender?.view {
        case view1:
            //do something
        case view2:
            //do something
        default:
            break
        }
    }
猫弦 2024-10-20 04:02:13

您可以使用此代码来完成此操作,我的视图是 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;
        }
    }
}

You can do it using this code my views which are imageviews in the 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;
        }
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文