iOS 将 tapGesture 添加到多个视图

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6237693/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 20:13:15  来源:igfitidea点击:

iOS adding tapGesture to multiple Views

objective-ciosuiviewios4uigesturerecognizer

提问by Srikar Appalaraju

I have multiple views defined in my main view. I want to add single tap gesture to all these views. Below is the code I have written, but this registers a tap gesture to the last view that I add. So in the code below, tap is registered only for messagesView& not for other views. I have 2 questions:

我在主视图中定义了多个视图。我想为所有这些视图添加单击手势。下面是我编写的代码,但这会向我添加的最后一个视图注册一个点击手势。所以在下面的代码中,tap 只messagesView为其他视图注册,而不是为其他视图注册。我有两个问题:

  1. How do I register the same tapGesture to multiple Views?

  2. Lets assume I get this working, now all single taps from these views goto the same function called oneTap. In this function how do I distinguish from which view the tap is coming?

  1. 如何将相同的 tapGesture 注册到多个视图?

  2. 让我们假设我得到了这个工作,现在来自这些视图的所有单次点击都转到了名为oneTap. 在此功能中,我如何区分水龙头来自哪个视图?

Code:

代码:

@synthesize feedsView, peopleView, messagesView, photosView;

- (void)viewDidLoad
{
    [super viewDidLoad];

    UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(oneTap:)];
    [singleTap setNumberOfTapsRequired:1];
    [singleTap setNumberOfTouchesRequired:1];
    [feedsView addGestureRecognizer:singleTap];
    [peopleView addGestureRecognizer:singleTap];
    [messagesView addGestureRecognizer:singleTap];
    //[photosView addGestureRecognizer:singleTap];
    [singleTap release];

    return;
}

回答by justin

I had the same problem where it only added to the last view. There might be a better solution, but I just created a tag gesture for each view and linked them to the same selector method (oneTap:in your case). In order to distinguish which view activated the method, you can just tag your views, feedsView.tag = 0; peopleView.tag = 1;and so on. Then when the method is called:

我有同样的问题,它只添加到最后一个视图。可能有更好的解决方案,但我只是为每个视图创建了一个标记手势,并将它们链接到相同的选择器方法(oneTap:在您的情况下)。为了区分哪个视图激活了该方法,您可以只标记您的视图,feedsView.tag = 0; peopleView.tag = 1;依此类推。然后当方法被调用时:

- (void)oneTap:(UIGestureRecognizer *)gesture {
    int myViewTag = gesture.view.tag;  // now you know which view called
    // use myViewTag to specify individual actions;
}

回答by ma11hew28

  1. Can you attach a UIGestureRecognizer to multiple views?No.

  2. Two options:

    a) Give every UIGestureRecognizerits own action. Pluses of this approach: strong decoupling. Minuses: more code reuse. But, you can mitigate code reuse by creating methods for common functionalities and just call the methods in the different actions.

    b) Give every view to which you add a UIGestureRecognizera unique tag. Then, use a switch statement in the common action with the sender's view's tag as the case. Pluses: less code reuse. Minuses: tighter coupling. Something like this:

    UIGestureRecognizer *singleTap = [[UIGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapAction:)];
    [feedsView addGestureRecognizer:singleTap];
    feedsView.tag = 33;
    

    Then:

    - (void)singleTapAction:(UIGestureRecognizer *)singleTap {
        UIView *view = singleTap.view;
        switch (view.tag) {
            case 33
                // view is feedsView
                break;
    
            default:
                break;
        }
    }
    

    Although it's usually best to go with the option that decouples, if all of your actions are very similar, which seems to be the case here, and you are quite sure that they'll remain very similar in the future, then option b) with the tags is probably the better choice.

  1. 您可以将 UIGestureRecognizer 附加到多个视图吗?不。

  2. 两种选择:

    a) 给每一个UIGestureRecognizer自己的行动。这种方法的优点:强解耦。缺点:更多的代码重用。但是,您可以通过为通用功能创建方法并在不同操作中调用这些方法来减少代码重用。

    b) 为您添加UIGestureRecognizer唯一标签的每个视图提供。然后,以发送方视图的标签为案例,在通用操作中使用 switch 语句。优点:更少的代码重用。缺点:更紧密的耦合。像这样的东西:

    UIGestureRecognizer *singleTap = [[UIGestureRecognizer alloc] initWithTarget:self action:@selector(singleTapAction:)];
    [feedsView addGestureRecognizer:singleTap];
    feedsView.tag = 33;
    

    然后:

    - (void)singleTapAction:(UIGestureRecognizer *)singleTap {
        UIView *view = singleTap.view;
        switch (view.tag) {
            case 33
                // view is feedsView
                break;
    
            default:
                break;
        }
    }
    

    尽管通常最好使用解耦选项,但如果您的所有操作都非常相似(这里似乎就是这种情况),并且您非常确定它们将来会保持非常相似,那么选项 b) 与标签可能是更好的选择。

P.S. It's unnecessary to explicitly set numberOfTapsRequired& numberOfTouchesRequiredto 1since they're both set to 1by default. You can confirm this by holding Command and clicking on numberOfTapsRequiredin Xcode.

PS 没有必要显式设置numberOfTapsRequired& numberOfTouchesRequired1因为它们都是1默认设置的。您可以通过按住 Command 并numberOfTapsRequired在 Xcode 中单击来确认这一点。

回答by Ken

1 use hitTest:

1 使用hitTest:

CGPoint location = [singleTap locationInView:self.view];
id testView = [self.view hitTest:location withEvent:nil];

2 add THE Single TapGesture to multi views, only last view worked.

2 将单个 TapGesture 添加到多视图,只有最后一个视图有效。

回答by kdhingra7

// Add tap gesture in swift 4

// 在 swift 4 中添加点击手势

    let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
    view.addGestureRecognizer(tap)
    view.isUserInteractionEnabled = true
    self.view.addSubview(view)

// function which is triggered when handleTap is called
@objc func handleTap(_ sender: UITapGestureRecognizer) {
    if sender.view == view1 {
       // do something
    }
    else{
       // do next thing
    }
}

//USE in view did load: tapGestures(view: view1) tapGestures(view: view2) tapGestures(view: view3)

//USE in view did load: tapGestures(view: view1) tapGestures(view: view2) tapGestures(view: view3)

回答by lev4

Add one tap gesture to multiple views (in this case UILabel), using computed properties. It creates new recognizer for every call.

使用计算属性将一个点击手势添加到多个视图(在本例中为 UILabel)。它为每次调用创建新的识别器。

    var recognizer: UITapGestureRecognizer {
        get {
            return UITapGestureRecognizer(target: self, action: #selector(self.labelTapped(_:)))
        }
    }

    label1.addGestureRecognizer(recognizer)
    label2.addGestureRecognizer(recognizer)
    label3.addGestureRecognizer(recognizer)
    label4.addGestureRecognizer(recognizer)

and labelTapped function

和 labelTapped 函数

@objc func labelTapped(_ sender: UITapGestureRecognizer) {
    let tappedLabel:UILabel = (sender.view as! UILabel)
}

回答by Was'Siim Ben Hssen

to attach multiple views to same gesture you can reinitialize the gesture before affecting to your view

将多个视图附加到同一个手势,您可以在影响到您的视图之前重新初始化手势

here is an example in swift

这是一个快速的例子

override func viewDidLoad() {
    super.viewDidLoad()

    var tap = UITapGestureRecognizer(target: self, action: #selector(infoTapped(sender:)))
    tap.numberOfTapsRequired = 1
    info1Btn.addGestureRecognizer(tap)
    info1Btn.tag = 1

    tap = UITapGestureRecognizer(target: self, action: #selector(infoTapped(sender:)))
    info2Btn.addGestureRecognizer(tap)
    info2Btn.tag = 2

    tap = UITapGestureRecognizer(target: self, action: #selector(infoTapped(sender:)))
    info3Btn.addGestureRecognizer(tap)
    info3Btn.tag = 3

}


  @objc func infoTapped(sender: UITapGestureRecognizer){
    let view:UIView = sender.view!
    switch (view.tag) {
    case 1:
        print(view.tag) //  info 1 tapped
    case 2:
        print(view.tag) //  info2 tapped

    case 3:
        print(view.tag) //  info 3 tapped

    default:
        break;
    }
}