简体   繁体   English

如何在 swift 中以编程方式在 UIView 上调用手势点击

[英]How to call gesture tap on UIView programmatically in swift

I have a UIView and and I have added tap gesture to it:我有一个 UIView 并且我已经向它添加了点击手势:

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

I am trying to call it programmatically in the testfile.我试图在测试文件中以编程方式调用它。

sendActionForEvent

I am using this function, but it is not working:我正在使用此功能,但它不起作用:

myView.sendActionForEvent(UIEvents.touchUpDown)

It shows unrecognised selector sent to instance.它显示发送到实例的无法识别的选择器。

How can I solve this problem?我怎么解决这个问题?

You need to initialize UITapGestureRecognizer with a target and action, like so:您需要使用目标和操作初始化UITapGestureRecognizer ,如下所示:

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

Then, you should implement the handler, which will be called each time when a tap event occurs:然后,您应该实现处理程序,每次点击事件发生时都会调用该处理程序:

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

So now calling your tap gesture recognizer event handler is as easy as calling a method:所以现在调用你的点击手势识别器事件处理程序就像调用一个方法一样简单:

handleTap()

For anyone who is looking for Swift 3 solution对于正在寻找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")
  }

For Swift 4 :对于斯威夫特 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")
}

In Swift 4, you need to explicitly indicate that the triggered function is callable from Objective-C, so you need to add @objc too your handleTap function.在 Swift 4 中,您需要明确指出触发的函数可以从 Objective-C 调用,因此您还需要在您的 handleTap 函数中添加 @objc。

See @Ali Beadle 's answer here: Swift 4 add gesture: override vs @objc在此处查看@Ali Beadle 的答案: Swift 4 add gesture: override vs @objc

Just a note - Don't forget to enabled interaction on the view:请注意 - 不要忘记在视图上启用交互:

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

view.addGestureRecognizer(tap)

// view.userInteractionEnabled = true

self.view.addSubview(view)

Implementing tap gesture实现点击手势

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

Calls this function when the tap is recognized.当点击被识别时调用此函数。

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

Update for For Swift 3 +为 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")
}

STEP : 1步骤1

@IBOutlet var viewTap: UIView!

STEP : 2第2步

var tapGesture = UITapGestureRecognizer()

STEP : 3步骤: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
}

STEP : 4第4步

func myviewTapped(_ sender: UITapGestureRecognizer) {

    if self.viewTap.backgroundColor == UIColor.yellow {
        self.viewTap.backgroundColor = UIColor.green
    }else{
        self.viewTap.backgroundColor = UIColor.yellow
    }
}

OUTPUT输出

在此处输入图像描述

Swift 5.1 Example for three view Swift 5.1三视图示例

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

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

Step:2 -> Add storyBoard view Tag步骤:2 -> 添加故事板视图标签

第一视图 第二视图 第三视图

Step:3 -> Add gesture步骤: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
    }

Step:4 -> select view步骤: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")
        }
    }

Swift 4斯威夫特 4

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

@objc func touchTapped(_ sender: UITapGestureRecognizer) {
}

This is how it works in Swift 3:这就是它在 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")
}

Complete answer for Swift 4 Swift 4 的完整答案

Step 1: create an outlet for the view第 1 步:为视图创建一个出口

@IBOutlet weak var rightViewOutlet: UIView!

Step 2: define a tap gesture第 2 步:定义轻击手势

var tapGesture = UITapGestureRecognizer()

Step 3: create ObjC function (called when view tapped)第 3 步:创建 ObjC 函数(在点击视图时调用)

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

Step 4: add the following within viewDidLoad()第 4 步:在 viewDidLoad() 中添加以下内容

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

I worked out on Xcode 6.4 on swift.我在 swift 上开发了 Xcode 6.4。 See below.见下文。

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
}

You need to initialize UITapGestureRecognizer with a target and action, like so:您需要使用目标和操作初始化 UITapGestureRecognizer,如下所示:

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

Then, you should implement the handler, which will be called each time when a tap event occurs:然后,您应该实现处理程序,每次点击事件发生时都会调用该处理程序:

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

If you want Objective C code is given below,如果你想要下面给出的 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");
}

or you want swift code is given below,或者你想要下面给出的快速代码,

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

try the following extension尝试以下扩展

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
}

and then use it :然后使用它:

submitBtn.addTapGesture {
     //your code
}

you can even use it for cell你甚至可以将它用于细胞

cell.addTapGesture {
     //your code
}

Here is the simplest way to add Gestures on View in Swift 5这是在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")
        }
    }
}
    let tap = UITapGestureRecognizer(target: self, action: Selector("handleFrontTap:"))
    frontView.addGestureRecognizer(tap)

// Make sure this is not private
func handleFrontTap(gestureRecognizer: UITapGestureRecognizer) {
    print("tap working")
}

Swift 4斯威夫特 4

First, create an object of UITapGestureRecognizer首先,创建一个UITapGestureRecognizer的对象

var tapGesture = UITapGestureRecognizer()

The second step is to initialise UITapGestureReconizer.第二步是初始化 UITapGestureReconizer。 Enable the user interaction, then add it.启用用户交互,然后添加它。

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

Third, create a method三、创建方法

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

I worked out on Xcode 7.3.1 on Swift 2.2.我在 Swift 2.2 上开发了 Xcode 7.3.1。 See below.见下文。

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

func handleTap() {
    // Your code here...
}

I wanted to specify two points which kept causing me problems.我想指定两个一直给我带来问题的点。

  • I was creating the Gesture Recognizer on init and storing it in a let property.我在 init 上创建手势识别器并将其存储在 let 属性中。 Apparently, adding this gesture recog to the view does not work.显然,将此手势识别添加到视图中不起作用。 May be self object passed to the gesture recognizer during init, is not properly configured.可能是在初始化期间传递给手势识别器的 self 对象,未正确配置。
  • The gesture recognizer should not be added to views with zero frames.不应将手势识别器添加到零帧视图中。 I create all my views with zero frame and then resize them using autolayout.我用零帧创建所有视图,然后使用自动布局调整它们的大小。 The gesture recognizers have to be added AFTER the views have been resized by the autolayout engine.必须在自动布局引擎调整视图大小后添加手势识别器。 So I add the gesture recognizer in viewDidAppear and they work.所以我在 viewDidAppear 中添加了手势识别器,它们就可以工作了。

xCode 9.3, Swift 4.0 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) {

     }
}

Inside ViewDidLoad 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: [:])
    }
}

Calling Purpose调用目的

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

Mail Purpose邮件目的

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

Try the following swift code (tested in Xcode 6.3.1):尝试以下 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);
        }
      }
    }

Note that your target could be any subclass of UIResponder, see (tested in Xcode 6.3.1):请注意,您的目标可以是 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!)
      }
    }

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

For anyone looking to activate a views tap gesture recognizer without having direct access to the gesture recognizer... when returning to a page I had to fill bubbles that were previously filled by tapping.对于任何想要激活视图的点击手势识别器而无需直接访问手势识别器......当返回页面时,我必须填充之前通过点击填充的气泡。 I kept track of those bubbles tags (bubs) ...我一直在跟踪那些气泡标签(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)
}


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

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