简体   繁体   English

iOS 将点击手势添加到多个视图

[英]iOS adding tapGesture to multiple Views

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.因此,在下面的代码中,tap 仅注册为messagesView而不是其他视图。 I have 2 questions:我有两个问题:

  1. How do I register the same tapGesture to multiple Views?如何将相同的 tapGesture 注册到多个视图?

  2. Lets assume I get this working, now all single taps from these views goto the same function called oneTap .假设我可以正常工作,现在这些视图中的所有单击都转到名为oneTap In this function how do I distinguish from which view the tap is coming?在这个 function 中,我如何区分水龙头来自哪个视图?

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

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).可能有更好的解决方案,但我只是为每个视图创建了一个标记手势并将它们链接到相同的选择器方法( oneTap:在你的情况下)。 In order to distinguish which view activated the method, you can just tag your views, feedsView.tag = 0; peopleView.tag = 1;为了区分哪个视图激活了方法,你可以只标记你的视图, feedsView.tag = 0; peopleView.tag = 1; feedsView.tag = 0; peopleView.tag = 1; and so on.等等。 Then when the method is called:然后当方法被调用时:

- (void)oneTap:(UIGestureRecognizer *)gesture {
    int myViewTag = gesture.view.tag;  // now you know which view called
    // use myViewTag to specify individual actions;
}
  1. Can you attach a UIGestureRecognizer to multiple views? 您可以将 UIGestureRecognizer 附加到多个视图吗? No.不。

  2. Two options:两种选择:

    a) Give every UIGestureRecognizer its own action. a) 给每个UIGestureRecognizer自己的动作。 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 UIGestureRecognizer a unique tag. b) 为您添加UIGestureRecognizer的每个视图提供一个唯一标记。 Then, use a switch statement in the common action with the sender's view's tag as the case.然后,以发送者视图的标签为例,在通用动作中使用 switch 语句。 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.虽然通常最好 go 使用解耦选项,但如果您的所有操作都非常相似,这似乎是这里的情况,并且您非常确定它们将来会保持非常相似,那么选项 b) 与标签可能是更好的选择。

PS It's unnecessary to explicitly set numberOfTapsRequired & numberOfTouchesRequired to 1 since they're both set to 1 by default. PS 没有必要将numberOfTapsRequirednumberOfTouchesRequired显式设置为1 ,因为默认情况下它们都设置为1 You can confirm this by holding Command and clicking on numberOfTapsRequired in Xcode.您可以通过按住 Command 并单击 Xcode 中的numberOfTapsRequired来确认这一点。

Add one tap gesture to multiple views (in this case UILabel), using computed properties.使用计算属性将一键手势添加到多个视图(在本例中为 UILabel)。 It creates new recognizer for every call.它为每个呼叫创建新的识别器。

    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 function

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

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 将 Single TapGesture 添加到多视图,只有最后一个视图有效。

// 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) //在视图中使用确实加载了:tapGestures(view: view1) tapGestures(view: view2) tapGestures(view: view3)

to attach multiple views to same gesture you can reinitialize the gesture before affecting to your view要将多个视图附加到同一手势,您可以在影响视图之前重新初始化手势

here is an example in swift这是 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;
    }
}
for index in 0..3 {
       let view = UIView()
       view.tag = index
       let gestureRecognizer = UITapGestureRecognizer(target: self, action:  #selector(self.viewTapped(_:)))
       view.addGestureRecognizer(gestureRecognizer)
       myViews.append(view)
    }

@objc func viewTapped( _ sender: UITapGestureRecognizer) { 
    guard let tappedView = sender.view as? SelectableFeeIKEABtnView else { return }
    for view in myViews {
        if tappedView.tag == view.tag {
          //Do something
        }
    }
}

In this example there is a loop that creates 4 different views, assigns them the same tap gesture and appends them in an array called myViews .在这个例子中,有一个循环创建 4 个不同的视图,为它们分配相同的点击手势,并将它们附加到一个名为myViews的数组中。 Besides, it is important to set a different tag to each of them, in this case I'm using their position in the array (index) as the tag.此外,为每个人设置不同的标签很重要,在这种情况下,我在数组(索引)中使用他们的 position 作为标签。

Once you have the differentiated with the tags you can compare in the function @objc func viewTapped( _ sender: UITapGestureRecognizer) if the view tapped is the view you are interested in.一旦您与标签进行了区分,您可以在 function @objc func viewTapped(_ sender: UITapGestureRecognizer)中进行比较,如果点击的视图是您感兴趣的视图。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM