【问题标题】:How to call gesture tap on UIView programmatically in swift如何在 swift 中以编程方式在 UIView 上调用手势点击
【发布时间】:2015-04-24 20:39:34
【问题描述】:

我有一个 UIView 并且我已经向它添加了点击手势:

let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
tap.delegate = self
myView.addGesture(tap)

我试图在测试文件中以编程方式调用它。

sendActionForEvent

我正在使用这个功能,但它不起作用:

myView.sendActionForEvent(UIEvents.touchUpDown)

它显示发送到实例的无法识别的选择器。

我该如何解决这个问题?

【问题讨论】:

  • 在 swift 2.2 中你可以使用新的选择器语法:let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
  • @wujo - 谢谢你;奇怪的是它实际上对我不起作用,在 UIView 中可能只在视图控制器中?
  • 如果您使用图像视图,请记住imageView.userInteractionEnabled = true。被抓住太久了。
  • @Josh,是的,很重要的一点。
  • @KhangAzun 最好的选择是直接调用tap函数

标签: ios swift iphone ios8 uigesturerecognizer


【解决方案1】:

您需要使用目标和操作初始化UITapGestureRecognizer,如下所示:

let tap = UITapGestureRecognizer(target: self, action: #selector(self.handleTap(_:)))
myView.addGestureRecognizer(tap)

然后,你应该实现处理程序,每次点击事件发生时都会调用它:

@objc func handleTap(_ sender: UITapGestureRecognizer? = nil) {
    // handling code
}

所以现在调用你的点击手势识别器事件处理程序就像调用一个方法一样简单:

handleTap()

【讨论】:

  • 我不想直接调用选择器函数,而是想通过编程调用 UITapGestureRecognizer 事件来调用它
  • @muhasturk 不要改变赞成的答案的含义。您的编辑使旧 Swift 版本的答案无效。如果您想发布 Swift 2.2 的更新,请发布您自己的答案。谢谢。
  • tap.delegate = self 不需要,因为您已经设置了目标和操作
  • 在Swift3中抛出错误,你的handle tap函数应该是:func handleTap(_ sender: UITapGestureRecognizer)
  • 调用函数应该是......func handleTap(_ sender: UITapGestureRecognizer? = nil) ...... ....你错过了“_”........所以你的调用函数不起作用..
【解决方案2】:

对于正在寻找 Swift 3 解决方案的任何人

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) {
     print("Hello World")
  }

【讨论】:

  • isUserInteractionEnabled 真的有必要吗?默认为假?
  • 当您的视图是 ImageView 或 UIVIew 的任何子类而不是 UIControl 时,view.isUserInteractionEnabled = true 是键。
【解决方案3】:

对于 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) {
    print("Hello World")
}

在 Swift 4 中,您需要明确指出触发的函数可以从 Objective-C 调用,因此您需要在 handleTap 函数中也添加 @objc。

在此处查看@Ali Beadle 的答案:Swift 4 add gesture: override vs @objc

【讨论】:

  • 当您的视图是 ImageView 或 UIVIew 的任何子类而不是 UIControl 时,view.isUserInteractionEnabled = true 是键。
【解决方案4】:

请注意 - 不要忘记在视图上启用交互:

let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap))

view.addGestureRecognizer(tap)

// view.userInteractionEnabled = true

self.view.addSubview(view)

【讨论】:

  • 备注很重要!
【解决方案5】:

实现点击手势

let tap: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "touchHappen") 
view.userInteractionEnabled = true
view.addGestureRecognizer(tap)

当点击被识别时调用这个函数。

func touchHappen() {
    //Causes the view (or one of its embedded text fields) to resign the first responder status.
    self.view.endEditing(true)
}

适用于 Swift 3 + 的更新

let tap = UITapGestureRecognizer(target: self, action: #selector(self.touchHappen(_:)))
yourView.addGestureRecognizer(tap)
yourView.userInteractionEnabled = true

func touchHappen(_ sender: UITapGestureRecognizer) {
    print("Hello Dear you are here")
}

【讨论】:

    【解决方案6】:

    步骤:1

    @IBOutlet var viewTap: UIView!
    

    步骤:2

    var tapGesture = UITapGestureRecognizer()
    

    步骤:3

    override func viewDidLoad() {
        super.viewDidLoad()
        // TAP Gesture
        tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.myviewTapped(_:)))
        tapGesture.numberOfTapsRequired = 1
        tapGesture.numberOfTouchesRequired = 1
        viewTap.addGestureRecognizer(tapGesture)
        viewTap.isUserInteractionEnabled = true
    }
    

    步骤:4

    func myviewTapped(_ sender: UITapGestureRecognizer) {
    
        if self.viewTap.backgroundColor == UIColor.yellow {
            self.viewTap.backgroundColor = UIColor.green
        }else{
            self.viewTap.backgroundColor = UIColor.yellow
        }
    }
    

    输出

    【讨论】:

      【解决方案7】:

      Swift 5.1 三视图示例

      Step:1 -> 添加storyboard view并添加outlet viewController UIView

      @IBOutlet var firstView: UIView!
      @IBOutlet var secondView: UIView!
      @IBOutlet var thirdView: UIView!
      

      步骤:2 -> 添加storyBoard视图标签

      步骤:3 -> 添加手势

      override func viewDidLoad() {
              super.viewDidLoad()
      
              firstView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tap(_:))))
              firstView.isUserInteractionEnabled = true
              secondView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tap(_:))))
              secondView.isUserInteractionEnabled = true
              thirdView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tap(_:))))
              thirdView.isUserInteractionEnabled = true
          }
      

      步骤:4 -> 选择视图

      @objc func tap(_ gestureRecognizer: UITapGestureRecognizer) {
              let tag = gestureRecognizer.view?.tag
              switch tag! {
              case 1 :
                  print("select first view")
              case 2 :
                  print("select second view")
              case 3 :
                  print("select third view")
              default:
                  print("default")
              }
          }
      

      【讨论】:

      • 您可以删除“isUserInteractionEnabled = true”行并将值直接放在属性检查器上,就在“标签”下方,您有“启用用户交互”复选框。
      【解决方案8】:

      斯威夫特 4

      let tap = UITapGestureRecognizer(target: self, action: #selector(self.touchTapped(_:)))
          self.view.addGestureRecognizer(tap)
      
      @objc func touchTapped(_ sender: UITapGestureRecognizer) {
      }
      

      【讨论】:

        【解决方案9】:

        这就是它在 Swift 3 中的工作方式:

        @IBOutlet var myView: UIView!
        override func viewDidLoad() {
            super.viewDidLoad()
        
            let tap = UITapGestureRecognizer(target: self, action:#selector(handleTap))
        
            myView.addGestureRecognizer(tap)
        }
        
        func handleTap() {
            print("tapped")
        }
        

        【讨论】:

          【解决方案10】:

          Swift 4 的完整答案

          第一步:为视图创建一个出口

          @IBOutlet weak var rightViewOutlet: UIView!
          

          第 2 步:定义点击手势

          var tapGesture = UITapGestureRecognizer()
          

          第 3 步:创建 ObjC 函数(在点击视图时调用)

          @objc func rightViewTapped(_ recognizer: UIGestureRecognizer) {
              print("Right button is tapped")
          }
          

          第 4 步:在 viewDidLoad() 中添加以下内容

          let rightTap = UITapGestureRecognizer(target: self, action: #selector(ViewController.rightViewTapped(_:)))
              rightViewOutlet.addGestureRecognizer(rightTap)
          

          【讨论】:

          • 第 2 步不是必需的。
          【解决方案11】:

          我在 swift 上开发了 Xcode 6.4。见下文。

          var view1: UIView!
          
          func assignTapToView1() {          
            let tap = UITapGestureRecognizer(target: self, action: Selector("handleTap"))
            //  tap.delegate = self
            view1.addGestureRecognizer(tap)
            self.view .addSubview(view1)
          
          ...
          }
          
          func handleTap() {
           print("tap working")
           view1.removeFromSuperview()
           // view1.alpha = 0.1
          }
          

          【讨论】:

            【解决方案12】:

            如果你想要下面给出Objective C代码,

            UITapGestureRecognizer *gesRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; // Declare the Gesture.
            gesRecognizer.delegate = self;
            [yourView addGestureRecognizer:gesRecognizer]; // Add Gesture to your view.
            
            // Declare the Gesture Recognizer handler method.
            
            - (void)handleTap:(UITapGestureRecognizer *)gestureRecognizer{
               NSLog(@"Tapped");
            }
            

            或者你想要快速的代码如下,

            import UIKit
            class ViewController: UIViewController {
            
                @IBOutlet weak var myView: UIView!
            
                override func viewDidLoad() {
                    super.viewDidLoad()
            
                    // Add tap gesture recognizer to view
                    let tapGesture = UITapGestureRecognizer(target: self, action: Selector("handleTap:"))
                    myView.addGestureRecognizer(tapGesture)
                }
            
                // this method is called when a tap is recognized
                func handleTap(sender: UITapGestureRecognizer) {
            
                    print("tap")
                }
            }
            

            【讨论】:

              【解决方案13】:

              您需要使用目标和操作来初始化 UITapGestureRecognizer,如下所示:

              let tap = UITapGestureRecognizer(target: self, action: "handleTap:")
              tap.delegate = self
              myView.addGestureRecognizer(tap)
              

              然后,你应该实现处理程序,每次点击事件发生时都会调用它:

              func handleTap(sender: UITapGestureRecognizer) {
                // handling code
              }
              

              【讨论】:

                【解决方案14】:
                    let tap = UITapGestureRecognizer(target: self, action: Selector("handleFrontTap:"))
                    frontView.addGestureRecognizer(tap)
                
                // Make sure this is not private
                func handleFrontTap(gestureRecognizer: UITapGestureRecognizer) {
                    print("tap working")
                }
                

                【讨论】:

                  【解决方案15】:

                  斯威夫特 4

                  首先,创建一个UITapGestureRecognizer的对象

                  var tapGesture = UITapGestureRecognizer()
                  

                  第二步是初始化UITapGestureReconizer。启用用户 交互,然后添加它。

                  override func viewDidLoad() {
                          super.viewDidLoad()
                      tapGesture = UITapGestureRecognizer(target: self, action: #selector(YourViewController.myviewTapped(_:)))
                              infosView.isUserInteractionEnabled = true
                              infosView.addGestureRecognizer(tapGesture)
                  view.addSubview(infosView)
                  }
                  

                  三、创建方法

                  @objc func myviewTapped(_ recognizer: UIGestureRecognizer) {
                                  print("button is tapped")
                              }
                  

                  【讨论】:

                    【解决方案16】:

                    我在 Swift 2.2 上开发了 Xcode 7.3.1。见下文。

                    func addTapGesture() {
                        let tap = UITapGestureRecognizer(target: self, action: #selector(MyViewController.handleTap))
                        tap.numberOfTapsRequired = 1
                        self.myView.addGestureRecognizer(tap)
                    }
                    
                    func handleTap() {
                        // Your code here...
                    }
                    

                    【讨论】:

                    • 在你的viewDidLoad()中添加addTapGesture()
                    【解决方案17】:

                    试试下面的扩展

                        extension UIView {
                    
                        func  addTapGesture(action : @escaping ()->Void ){
                            let tap = MyTapGestureRecognizer(target: self , action: #selector(self.handleTap(_:)))
                            tap.action = action
                            tap.numberOfTapsRequired = 1
                    
                            self.addGestureRecognizer(tap)
                            self.isUserInteractionEnabled = true
                    
                        }
                        @objc func handleTap(_ sender: MyTapGestureRecognizer) {
                            sender.action!()
                        }
                    }
                    
                    class MyTapGestureRecognizer: UITapGestureRecognizer {
                        var action : (()->Void)? = nil
                    }
                    

                    然后使用它:

                    submitBtn.addTapGesture {
                         //your code
                    }
                    

                    你甚至可以将它用于单元格

                    cell.addTapGesture {
                         //your code
                    }
                    

                    【讨论】:

                    • 虽然只有代码的答案确实是一个答案,但有点解释(为什么 OP 的代码不起作用,你的代码背后的一般思想是什么,重点,警告,......)可以使它成为一个更好的答案。
                    【解决方案18】:

                    我想指出两个一直给我带来问题的点。

                    • 我在 init 上创建手势识别器并将其存储在 let 属性中。显然,将此手势识别添加到视图中不起作用。可能是在初始化期间传递给手势识别器的 self 对象,未正确配置。
                    • 不应将手势识别器添加到零帧视图中。我用零帧创建所有视图,然后使用自动布局调整它们的大小。必须在自动布局引擎调整视图大小后添加手势识别器。所以我在 viewDidAppear 中添加了手势识别器,它们就可以工作了。

                    【讨论】:

                      【解决方案19】:

                      xCode 9.3,斯威夫特 4.0

                      class BaseVC: UIViewController, UIGestureRecognizerDelegate { 
                      
                            @IBOutlet weak var iView: UIView!
                      
                            override func viewDidLoad() {
                                super.viewDidLoad()
                                let clickUITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(self.onSelect(_:)))
                                clickUITapGestureRecognizer.delegate = self
                                iView?.addGestureRecognizer(tap)
                            }
                      
                            func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
                                return true
                            }
                      
                      
                           @IBAction func onSelect(_ sender: Any) {
                      
                           }
                      }
                      

                      【讨论】:

                      • 函数onSelect不需要是IBAction
                      • iView?.addGestureRecognizer(tap) 你的gestureRecognizer的名字是clickUITapGestureRecognizer 所以正确的做法是:iView?.addGestureRecognizer(clickUITapGestureRecognizer)
                      【解决方案20】:

                      ViewDidLoad 内部

                      let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(imageTapped(tapGestureRecognizer:)))
                          self.imgMainAdView.isUserInteractionEnabled = true
                          self.imgMainAdView.addGestureRecognizer(tapGestureRecognizer)
                      

                      //MARK: - Image Tap Method -
                      @objc func imageTapped(tapGestureRecognizer: UITapGestureRecognizer)
                      {
                          print("Tapped")
                          if let url = URL(string: self.strMAinAdvLink)
                          {
                              UIApplication.shared.open(url, options: [:])
                          }
                      }
                      

                      调用目的

                      @IBAction func btnCall1Action(_ sender: Any)
                      {
                          let text = self.strPhoneNumber1!
                          let test = String(text.filter { !" -()".contains($0) })
                          UIApplication.shared.openURL(NSURL(string: "tel://\(test)")! as URL)
                      }
                      

                      邮件目的

                      MFMailComposeViewControllerDelegate
                      
                       @IBAction func btnMailAction(_ sender: Any)
                      {
                          let strEmail = SAFESTRING(str:  (self.dictEventDetails?.value(forKeyPath: "Email.value_text.email") as! String))
                      
                          if !MFMailComposeViewController.canSendMail()
                          {
                              AppDelegate.sharedInstance().showAlertAction(strTitle: "OK", strMessage: "Mail services are not available") { (success) in
                              }
                              return
                          }
                          let composeVC = MFMailComposeViewController()
                          composeVC.mailComposeDelegate = self
                          composeVC.setToRecipients([strEmail])
                          composeVC.setSubject("")
                          composeVC.setMessageBody("", isHTML: false)
                          self.present(composeVC, animated: true, completion: nil)
                      }
                      func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?)
                      {
                          controller.dismiss(animated: true, completion: nil)
                      }
                      

                      【讨论】:

                        【解决方案21】:

                        这是在 Swift 5

                        中在视图上添加手势的最简单方法
                        import UIKit
                        
                        class ViewController: UIViewController {
                        
                            override func viewDidLoad() {
                                super.viewDidLoad()
                                addGestures()
                            }
                        
                            // MARK: Add Gestures to target view
                            func addGestures()
                            {
                                // 1. Single Tap or Touch
                                let tapGesture = UITapGestureRecognizer(target: self, action: #selector(self.tapGetstureDetected))
                                tapGesture.numberOfTapsRequired = 1
                                view.addGestureRecognizer(tapGesture)
                        
                                //2. Double Tap
                                let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(self.doubleTapGestureDetected))
                                doubleTapGesture.numberOfTapsRequired = 2
                                view.addGestureRecognizer(doubleTapGesture)
                        
                                //3. Swipe
                                let swipeGesture = UISwipeGestureRecognizer(target: self, action: #selector(self.swipeGetstureDetected))
                                view.addGestureRecognizer(swipeGesture)
                        
                                //4. Pinch
                                let pinchGesture = UIPinchGestureRecognizer(target: self, action: #selector(self.pinchGetstureDetected))
                                view.addGestureRecognizer(pinchGesture)
                        
                                //5. Long Press
                                let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.longPressGetstureDetected))
                                view.addGestureRecognizer(longPressGesture)
                        
                                //6. Pan
                                let panGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.panGestureDetected))
                                view.addGestureRecognizer(panGesture)
                        
                            }
                        
                            // MARK: Handle Gesture detection
                            @objc func swipeGetstureDetected() {
                                print("Swipe Gesture detected!!")
                            }
                        
                            @objc func tapGetstureDetected() {
                                print("Touch/Tap Gesture detected!!")
                            }
                        
                            @objc func pinchGetstureDetected() {
                                print("Pinch Gesture detected!!")
                            }
                        
                            @objc func longPressGetstureDetected() {
                                print("Long Press Gesture detected!!")
                            }
                        
                            @objc func doubleTapGestureDetected() {
                                print("Double Tap Gesture detected!!")
                            }
                        
                            @objc func panGestureDetected()
                            {
                                print("Pan Gesture detected!!")
                            }
                        
                        
                            //MARK: Shake Gesture
                            override func becomeFirstResponder() -> Bool {
                                return true
                            }
                            override func motionEnded(_ motion: UIEvent.EventSubtype, with event: UIEvent?){
                                if motion == .motionShake
                                {
                                    print("Shake Gesture Detected")
                                }
                            }
                        }
                        

                        【讨论】:

                          【解决方案22】:

                          尝试以下 swift 代码(在 Xcode 6.3.1 中测试):

                              import UIKit
                          
                              class KEUITapGesture150427 : UIViewController {
                                var _myTap: UITapGestureRecognizer?
                                var _myView: UIView?
                          
                                override func viewDidLoad() {
                                  super.viewDidLoad()
                                  view.backgroundColor = UIColor.whiteColor();
                          
                                  _myTap = UITapGestureRecognizer(target: self
                          , action: Selector("_myHandleTap:"))
                                  _myTap!.numberOfTapsRequired = 1
                          
                                  _myView = UIView(frame: CGRectMake(100, 200, 100, 100))
                                  _myView!.backgroundColor=UIColor.blueColor()
                                  _myView!.layer.cornerRadius = 20
                                  _myView!.layer.borderWidth = 1
                                  _myView!.addGestureRecognizer(_myTap!)
                                  view.addSubview(_myView!)
                                }
                          
                                func _myHandleTap(sender: UITapGestureRecognizer) {
                                  if sender.state == .Ended {
                                    println("_myHandleTap(sender.state == .Ended)")
                                    sender.view!.backgroundColor
                                    = UIColor(red: CGFloat(drand48()), green: CGFloat(drand48()), blue: CGFloat(drand48()), alpha: 1.0);
                                  }
                                }
                              }
                          

                          请注意,您的目标可以是 UIResponder 的任何子类,请参阅(在 Xcode 6.3.1 中测试):

                              import UIKit
                          
                              class MyTapTarget  : UIResponder {
                                func _myHandleTap2(sender: UITapGestureRecognizer) {
                                  if sender.state == .Ended {
                                    println("_myHandleTap2(sender.state == .Ended)")
                                    sender.view!.backgroundColor
                                      = UIColor(red: CGFloat(drand48()), green: CGFloat(drand48()), blue: CGFloat(drand48()), alpha: 1.0);
                                  }
                                }
                              }
                          
                              class KEUITapGesture150427b : UIViewController {
                                var _myTap: UITapGestureRecognizer?
                                var _myView: UIView?
                                var _myTapTarget: MyTapTarget?
                          
                                override func viewDidLoad() {
                                  super.viewDidLoad()
                                  view.backgroundColor = UIColor.whiteColor();
                          
                                  _myTapTarget = MyTapTarget()
                                  _myTap = UITapGestureRecognizer(target: _myTapTarget!
                          , action: Selector("_myHandleTap2:"))
                                  _myTap!.numberOfTapsRequired = 1
                          
                                  _myView = UIView(frame: CGRectMake(100, 200, 100, 100))
                                  _myView!.backgroundColor=UIColor.blueColor()
                                  _myView!.layer.cornerRadius = 20
                                  _myView!.layer.borderWidth = 1
                                  _myView!.addGestureRecognizer(_myTap!)
                                  view.addSubview(_myView!)
                                }
                              }
                          

                          【讨论】:

                            【解决方案23】:

                            不用调用myView的UITapGestureRecognizer,可以直接调用handleTap函数,

                            【讨论】:

                              【解决方案24】:

                              对于想要激活视图的点击手势识别器而无需直接访问手势识别器的人......当返回页面时,我必须填充之前通过点击填充的气泡。我一直在跟踪那些气泡标签(bubs)...

                              func fillBubs(bubs: [Int]) {
                                  for bub in bubs {
                                      let bubble = view.viewWithTag(bub)
                                      if bubble == nil {continue}
                                      for g in bubble!.gestureRecognizers! {
                                          let tap = g as! UITapGestureRecognizer
                                          handleBub(tap)
                                      }
                                  }
                              }
                              
                              @objc func handleBub(_ sender: UITapGestureRecognizer? = nil) {
                                  let bubble = sender?.view!
                                  bubble?.layer.backgroundColor = #colorLiteral(red: 0, green: 0, blue: 0, alpha: 1)
                              }
                              
                              
                              

                              【讨论】:

                                猜你喜欢
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2016-12-21
                                • 1970-01-01
                                • 1970-01-01
                                • 1970-01-01
                                • 2016-06-30
                                相关资源
                                最近更新 更多