Cómo llamar gestos toque en UIView programáticamente en rápido

165

Tengo una UIView y le agregué un gesto de toque:

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

Estoy tratando de llamarlo mediante programación en el archivo de prueba.

sendActionForEvent

Estoy usando esta función, pero no funciona:

myView.sendActionForEvent(UIEvents.touchUpDown)

Muestra el selector no reconocido enviado a la instancia.

¿Como puedó resolver esté problema?

Jorge
fuente
2
En swift 2.2 puede usar la nueva sintaxis del selector: let tap = UITapGestureRecognizer (target: self, action: #selector (self.handleTap (_ :)))
Wujo
@wujo: gracias por eso; extrañamente, en realidad no funciona para mí, en una UIView ¿Quizás solo en un controlador de vista?
Fattie
2
También recuerde tener imageView.userInteractionEnabled = truesi está utilizando una vista de imagen. Quedé atrapado en eso por mucho tiempo.
Josh
@ Josh, sí, un punto importante.
NeverHopeless
1
@KhangAzun la mejor opción es llamar directamente a la función de toque
George

Respuestas:

244

Debe inicializar UITapGestureRecognizercon un objetivo y una acción, así:

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

Luego, debe implementar el controlador, que se llamará cada vez que ocurra un evento tap:

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

Entonces, llamar a su controlador de eventos de reconocimiento de gestos de toque es tan fácil como llamar a un método:

handleTap()
Salavat Khanov
fuente
en lugar de llamar a la función de selector directamente, quiero llamarla mediante la invocación programática del evento UITapGestureRecognizer
George
2
@muhasturk No cambie el significado de una respuesta votada. Su edición invalidaba la respuesta para versiones anteriores de Swift. Si desea publicar una actualización para Swift 2.2, publique su propia respuesta. Gracias.
Eric Aya
17
tap.delegate = selfno es necesario, ya que usted estableció un objetivo y una acción
Daniel
44
Lanza un error en Swift3, la función de toque de su manejador debería ser: func handleTap (_ remitente: UITapGestureRecognizer)
Travis M.
La función de llamada debe ser ................ func handleTap (_ remitente: UITapGestureRecognizer? = Nil) ............... se perdió "_ "........ así que su función de llamada no estaba funcionando ..
Prasad Patil
94

Para cualquiera que esté buscando la solución 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
 func handleTap(_ sender: UITapGestureRecognizer) {
     print("Hello World")
  }
John Lim
fuente
1
isUserInteractionEnabledes realmente necesario? ¿El valor predeterminado es falso?
jose920405
66
view.isUserInteractionEnabled = truees la clave cuando su vista es ImageView o cualquier subclase de UIVIew en lugar de UIControl.
Pankaj Kulkarni
61

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

En Swift 4, debe indicar explícitamente que la función activada se puede llamar desde Objective-C, por lo que también debe agregar @objc a su función handleTap.

Vea la respuesta de @Ali Beadle aquí: Swift 4 agregar gesto: anular vs @objc

RNHTTR
fuente
view.isUserInteractionEnabled = truees la clave cuando su vista es ImageView o cualquier subclase de UIVIew en lugar de UIControl.
Pankaj Kulkarni
50

Solo una nota: no olvide habilitar la interacción en la vista:

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

view.addGestureRecognizer(tap)

// view.userInteractionEnabled = true

self.view.addSubview(view)
Eclewlow
fuente
1
¡La nota es importante!
Itai Spector
21

PASO 1

@IBOutlet var viewTap: UIView!

PASO 2

var tapGesture = UITapGestureRecognizer()

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

PASO 4

func myviewTapped(_ sender: UITapGestureRecognizer) {

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

SALIDA

ingrese la descripción de la imagen aquí

Kirit Modi
fuente
14

Implementando gesto de toque

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

Llama a esta función cuando se reconoce el toque.

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

Actualización para For Swift 3

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

func touchHappen(_ sender: UITapGestureRecognizer) {
    print("Hello Museer")
}
Museer Ahamad Ansari
fuente
11

Swift 4

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

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

Así es como funciona en 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")
}
Neen
fuente
7

Respuesta completa para Swift 4

Paso 1: crea una salida para la vista

@IBOutlet weak var rightViewOutlet: UIView!

Paso 2: define un gesto de toque

var tapGesture = UITapGestureRecognizer()

Paso 3: crear la función ObjC (llamada cuando se toca la vista)

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

Paso 4: agregue lo siguiente dentro de viewDidLoad ()

let rightTap = UITapGestureRecognizer(target: self, action: #selector(ViewController.rightViewTapped(_:)))
    rightViewOutlet.addGestureRecognizer(rightTap)
Jorge
fuente
El paso 2 no es obligatorio.
guido
7

Swift 5.1 Ejemplo para tres vistas

Paso: 1 -> Agregar vista de guión gráfico y agregar vista de salida Controlador UIView

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

Paso: 2 -> Agregar etiqueta de vista de StoryBoard

primera vista secondView thirdView

Paso: 3 -> Agregar gesto

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
    }

Paso: 4 -> seleccionar vista

@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")
        }
    }
ikbal
fuente
6

Trabajé en Xcode 6.4 en Swift. Vea abajo.

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
}
AG
fuente
5

Si desea que el código del Objetivo C se dé a continuación,

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

o desea que el código rápido se da a continuación,

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")
    }
}
Iyyappan Ravi
fuente
5

Debe inicializar UITapGestureRecognizer con un objetivo y una acción, así:

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

Luego, debe implementar el controlador, que se llamará cada vez que ocurra un evento tap:

func handleTap(sender: UITapGestureRecognizer) {
  // handling code
}
Amit Raj Modi
fuente
3
    let tap = UITapGestureRecognizer(target: self, action: Selector("handleFrontTap:"))
    frontView.addGestureRecognizer(tap)

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

Swift 4

Primero, cree un objeto de UITapGestureRecognizer

var tapGesture = UITapGestureRecognizer()

El segundo paso es inicializar UITapGestureReconizer. Habilite la interacción del usuario y luego agréguela.

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

Tercero, crea un método

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

prueba la siguiente extensión

    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
}

y luego úsalo:

submitBtn.addTapGesture {
     //your code
}

incluso puedes usarlo para celular

cell.addTapGesture {
     //your code
}
Mahdi Delavar
fuente
1
Si bien una respuesta de solo código es de hecho una respuesta, un poco de explicación (por qué el código del OP no funcionó, cuál es la idea general detrás de su código, puntos importantes, advertencias, ...) podría mejorarlo respuesta.
lfurini
2

Trabajé en Xcode 7.3.1 en Swift 2.2. Vea abajo.

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

func handleTap() {
    // Your code here...
}
Daya Kevin
fuente
1
agregue addTapGesture()en suviewDidLoad()
Daya Kevin
1

Quería especificar dos puntos que me seguían causando problemas.

  • Estaba creando el Gesture Recognizer en init y lo almacenaba en una propiedad let. Aparentemente, agregar este reconocimiento de gesto a la vista no funciona. Puede ser un objeto propio pasado al reconocedor de gestos durante init, no está configurado correctamente.
  • El reconocedor de gestos no debe agregarse a las vistas con cero cuadros. Creo todas mis vistas con fotograma cero y luego las cambio de tamaño usando autolayout. Los reconocedores de gestos deben agregarse DESPUÉS de que el motor de auto-distribución haya cambiado el tamaño de las vistas. Así que agrego el reconocedor de gestos en viewDidAppear y funcionan.
nnrales
fuente
1

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

     }
}
Rahul
fuente
La función onSelect no necesita ser IBAction
Illya Krit el
iView? .addGestureRecognizer (tap) El nombre de su gestoReconocidor es clickUITapGestureRecognizer Entonces, la forma correcta es: iView? .addGestureRecognizer (clickUITapGestureRecognizer)
Illya Krit
1

Vista interior

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

Propósito de la llamada

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

Propósito del correo

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)
}
Tej Patel
fuente
1

Aquí está la forma más simple de agregar gestos a la vista en 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")
        }
    }
}
swiftBoy
fuente
0

Pruebe el siguiente código rápido (probado en 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);
        }
      }
    }

Tenga en cuenta que su objetivo podría ser cualquier subclase de UIResponder, consulte (probado en 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!)
      }
    }
Dmitry Konovalov
fuente
0

En lugar de invocar UITapGestureRecognizer de myView, puede llamar directamente a la handleTapfunción,

budidino
fuente