【问题标题】:tap gesture recognizer - which object was tapped?点击手势识别器 - 哪个对象被点击了?
【发布时间】:2014-03-01 15:14:51
【问题描述】:

我是手势识别器的新手,所以这个问题可能听起来很傻:我正在将点击手势识别器分配给一堆 UIView。在该方法中是否有可能找出其中哪些被以某种方式被点击,或者我需要使用屏幕上被点击的点来找出它?

for (NSUInteger i=0; i<42; i++) {
        float xMultiplier=(i)%6;
        float yMultiplier= (i)/6;
        float xPos=xMultiplier*imageWidth;
        float yPos=1+UA_TOP_WHITE+UA_TOP_BAR_HEIGHT+yMultiplier*imageHeight;
        UIView *greyRect=[[UIView alloc]initWithFrame:CGRectMake(xPos, yPos, imageWidth, imageHeight)];
        [greyRect setBackgroundColor:UA_NAV_CTRL_COLOR];

        greyRect.layer.borderColor=[UA_NAV_BAR_COLOR CGColor];
        greyRect.layer.borderWidth=1.0f;
        greyRect.userInteractionEnabled=YES;
        [greyGridArray addObject:greyRect];
        [self.view addSubview:greyRect];
        NSLog(@"greyGrid: %i: %@", i, greyRect);

        //make them touchable
        UITapGestureRecognizer *letterTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(highlightLetter)];
        letterTapRecognizer.numberOfTapsRequired = 1;
        [greyRect addGestureRecognizer:letterTapRecognizer];
    }

【问题讨论】:

    标签: ios objective-c uigesturerecognizer uitapgesturerecognizer


    【解决方案1】:

    用参数定义你的目标选择器(highlightLetter:)

    UITapGestureRecognizer *letterTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(highlightLetter:)];
    

    然后你可以通过

    - (void)highlightLetter:(UITapGestureRecognizer*)sender {
         UIView *view = sender.view; 
         NSLog(@"%d", view.tag);//By tag, you can find out where you had tapped. 
    }
    

    【讨论】:

    • 谢谢!出于某种原因,我将 NSNotification 而不是 UITapGestureRecognizer 放在 highlightLetter 函数中
    【解决方案2】:

    问这个问题已经一年了,但仍然有人问。

    在特定视图上声明UITapGestureRecognizer 时,将标签分配为

    UITapGestureRecognizer *tapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(gestureHandlerMethod:)];
    [yourGestureEnableView addGestureRecognizer:tapRecognizer];
    yourGestureEnableView.tag=2;
    

    在你的处理程序中这样做

    -(void)gestureHandlerMethod:(UITapGestureRecognizer*)sender {
        if(sender.view.tag == 2) {
            // do something here
        }
    }
    

    【讨论】:

      【解决方案3】:

      这是 Swift 3 的更新和对 Mani 回答的补充。我建议将sender.view 与标记 UIView(或其他元素,取决于您要跟踪的内容)结合使用,以获得更“高级”的方法。

      1. 将 UITapGestureRecognizer 添加到例如一个 UIButton(您也可以将其添加到 UIViews 等)或数组中的一大堆项目,其中包含一个 for 循环和一个用于点击手势的第二个数组。
          let yourTapEvent = UITapGestureRecognizer(target: self, action: #selector(yourController.yourFunction)) 
          yourObject.addGestureRecognizer(yourTapEvent) // adding the gesture to your object
      
      1. 在同一个 testController 中定义函数(这是您的视图控制器的名称)。我们将在这里使用tags - 标签是Int ID,您可以使用yourButton.tag = 1 添加到您的UIView。如果你有一个像数组这样的元素的动态列表,你可以创建一个 for 循环,它遍历你的数组并添加一个标签,标签会逐渐增加

        func yourFunction(_ sender: AnyObject) {
            let yourTag = sender.view!.tag // this is the tag of your gesture's object
            // do whatever you want from here :) e.g. if you have an array of buttons instead of just 1:
            for button in buttonsArray {
              if(button.tag == yourTag) {
                // do something with your button
              }
            }
        }
        

      所有这一切的原因是因为在将 yourFunction 与 #selector 结合使用时,您无法为 yourFunction 传递更多参数。

      如果您有一个更复杂的 UI 结构,并且您希望将项目的父标签附加到您的点击手势,您可以使用let yourAdvancedTag = sender.view!.superview?.tag,例如获取该 UIView 内按下按钮的 UIView 标记;可用于缩略图+按钮列表等。

      【讨论】:

      • 我喜欢您对发件人超级视图的处理方式。与标签结合使用时,它可以提供良好的故障保护
      • @Septronic 谢谢!它在我的应用程序用例中运行良好
      【解决方案4】:

      很快就很简单了

      在 ViewDidLoad() 函数中编写这段代码

      let tap = UITapGestureRecognizer(target: self, action: #selector(tapHandler(gesture:)))
          tap.numberOfTapsRequired = 2
          tapView.addGestureRecognizer(tap)
      

      Handler部分可以在viewDidLoad中,也可以在viewDidLoad之外,batter放在扩展中

      @objc func tapHandler(gesture: UITapGestureRecognizer) {
          currentGestureStates.text = "Double Tap"
      } 
      

      这里我只是通过打印输出来测试代码 如果你想做一个动作,你可以做任何你想做的事 或更多练习和阅读

      【讨论】:

        【解决方案5】:

        在 Swift 中使用此代码

        func tappGeastureAction(sender: AnyObject) {
            if let tap = sender as? UITapGestureRecognizer {
                let point = tap.locationInView(locatedView)
                if filterView.pointInside(point, withEvent: nil) == true {
                    // write your stuff here                
                }
            }
        }
        

        【讨论】:

        • 能问一下locatedView和filterView是什么吗?
        【解决方案6】:

        你可以使用

         - (void)highlightLetter:(UITapGestureRecognizer*)sender {
             UIView *view = sender.view; 
             NSLog(@"%d", view.tag); 
        }
        

        view 将是识别点击手势的对象

        【讨论】:

          【解决方案7】:

          也可以使用 UIGestureRecognizer 的“shouldReceiveTouch”方法

          - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:     (UITouch *)touch {
               UIView *view = touch.view; 
               NSLog(@"%d", view.tag); 
          }    
          

          不要忘记设置手势识别器的委托。

          【讨论】:

            【解决方案8】:

            2019 年典型示例

            假设您有一个FaceView,这是某种图像。您将在屏幕上(或在集合视图、表格、堆栈视图或其他列表中)显示 许多

            FaceView 类中,您将需要一个变量“索引”

            class FaceView: UIView {
               var index: Int
            

            这样每个 FaceView 都可以自我感知它在屏幕上的“哪张脸”。

            因此,您必须将var index: Int 添加到相关类中。

            所以你在屏幕上添加了许多 FaceView ...

            let f = FaceView()
            f.index = 73
            .. you add f to your stack view, screen, or whatever.
            

            您现在向 f 添加点击

            f.addGestureRecognizer(UITapGestureRecognizer(target: self,
                                       action: #selector(tapOneOfTheFaces)))
            

            这是秘密:

            @objc func tapOneOfTheFaces(_ sender: UITapGestureRecognizer) {
                if let tapped = sender.view as? CirclePerson {
                    print("we got it: \(tapped.index)")
            

            您现在知道在您的表格、屏幕、堆栈视图或其他任何内容中点击了“哪个”面孔。

            就这么简单。

            【讨论】:

            • 我不确定这应该如何工作,因为 sender.view 是手势附加到的视图。不是被挖掘的视图。你把所有的秘密都泄露了吗?
            • 嗨@Maverick!假设您有一些大师班,可能是“Screen”或“StackView”之类的。代码“f.addGestureRecognizer...”将是 in 屏幕。 (“自我”是屏幕。)所以说(在屏幕中)你添加了 100 个。 sender.view 是(总是)被点击的东西。所有 100 个都发送到屏幕。所有 100 个都在 Screen 中调用相同的函数 tapOneOfTheFaces。就是这样!
            【解决方案9】:

            您应该修改手势识别器的创建以接受参数(添加冒号':')

            UITapGestureRecognizer *letterTapRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(highlightLetter:)];
            

            在你的方法 highlightLetter: 你可以访问附加到识别器的视图:

            -(IBAction) highlightLetter:(UITapGestureRecognizer*)recognizer
            {
                UIView *view = [recognizer view];
            }
            

            【讨论】:

              【解决方案10】:

              斯威夫特 5

              在我的例子中,我需要访问被点击的 UILabel,因此您可以在手势识别器中执行此操作。

              let label:UILabel = gesture.view as! UILabel
              

              gesture.view 属性包含点击的视图,您可以简单地将其向下转换为您知道的视图。

              @IBAction func tapLabel(gesture: UITapGestureRecognizer) {
              
                      let label:UILabel = gesture.view as! UILabel
              
                      guard let text = label.attributedText?.string else {
                          return
                      }
              
                      print(text)
              }
              

              因此,您可以对 tapLabel 函数和 viewDidLoad 执行类似上述操作...

              <Label>.addGestureRecognizer(UITapGestureRecognizer(target:self, action: #selector(tapLabel(gesture:))))
              

              只需将&lt;Label&gt; 替换为您的实际标签名称

              【讨论】:

                【解决方案11】:

                如果您在不同的UIViews 上添加不同的UIGestureRecognizer 并希望在操作方法中进行区分,那么您可以检查 sender 参数中的属性视图,它将为您提供发送者视图。

                【讨论】:

                  【解决方案12】:
                  func tabGesture_Call
                  {
                       let tapRec = UITapGestureRecognizer(target: self, action: "handleTap:")
                       tapRec.delegate = self
                       self.view.addGestureRecognizer(tapRec)
                       //where we want to gesture like: view, label etc
                  }
                  
                  func handleTap(sender: UITapGestureRecognizer) 
                  {
                       NSLog("Touch..");
                       //handling code
                  }
                  

                  【讨论】:

                  • 您能解释一下您的答案如何解决问题中的问题吗?仅代码的答案不是很有用,特别是对于偶然发现这篇文章的更多读者。谢谢!
                  猜你喜欢
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2021-09-27
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 1970-01-01
                  • 2016-04-28
                  相关资源
                  最近更新 更多