Come chiamare il gesto tocca UIView a livello di codice in modo rapido


167

Ho un UIView e ho aggiunto il gesto del tocco ad esso:

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

Sto provando a chiamarlo programmaticamente nel file di test.

sendActionForEvent

Sto usando questa funzione, ma non funziona:

myView.sendActionForEvent(UIEvents.touchUpDown)

Mostra il selettore non riconosciuto inviato all'istanza.

Come posso risolvere questo problema?


2
In swift 2.2 puoi usare la nuova sintassi del selettore: let tap = UITapGestureRecognizer (target: self, action: #selector (self.handleTap (_ :)))
Wujo

@wujo - grazie per quello; stranamente in realtà non funziona per me, in un UIView Forse solo in un controller di visualizzazione?
Fattie,

2
Ricorda anche di avere imageView.userInteractionEnabled = truese stai usando una vista immagine. L'ho preso troppo a lungo.
Josh,

@Josh, sì, un punto importante.
NeverHopeless,

1
@KhangAzun l'opzione migliore è quella di chiamare direttamente la funzione tap
George

Risposte:


246

È necessario inizializzare UITapGestureRecognizercon un obiettivo e un'azione, in questo modo:

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

Quindi, è necessario implementare il gestore, che verrà chiamato ogni volta che si verifica un evento di tocco:

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

Quindi ora chiamare il gestore dell'evento del riconoscimento dei gesti dei tocchi è facile come chiamare un metodo:

handleTap()

invece di chiamare direttamente la funzione di selezione, voglio chiamarla invocando programmaticamente l'evento UITapGestureRecognizer
George,

2
@muhasturk Non cambia il significato di una risposta votata. La modifica stava invalidando la risposta per le versioni precedenti di Swift. Se desideri pubblicare un aggiornamento per Swift 2.2, pubblica la tua risposta. Grazie.
Eric Aya,

17
tap.delegate = selfnon è necessario, poiché hai già fissato un obiettivo e un'azione
Daniel,

4
Genera un errore in Swift3, la tua funzione di tocco della maniglia dovrebbe essere: func handleTap (_ mittente: UITapGestureRecognizer)
Travis M.

La funzione di chiamata deve essere ................ func handleTap (_ mittente: UITapGestureRecognizer? = Zero) ............... hai perso "_ "........ quindi la tua funzione di chiamata non funzionava ..
Prasad Patil,

94

Per chiunque cerchi la soluzione 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")
  }

1
isUserInteractionEnabledè davvero necessario? il valore predefinito è falso?
jose920405,

6
view.isUserInteractionEnabled = trueè la chiave quando la vista è ImageView o qualsiasi sottoclasse di UIVIew anziché UIControl.
Pankaj Kulkarni,

61

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

In Swift 4, è necessario indicare esplicitamente che la funzione attivata è richiamabile da Objective-C, quindi è necessario aggiungere anche @objc alla funzione handleTap.

Vedi la risposta di @Ali Beadle qui: Swift 4 aggiungi gesto: sovrascrivi vs @objc


view.isUserInteractionEnabled = trueè la chiave quando la vista è ImageView o qualsiasi sottoclasse di UIVIew anziché UIControl.
Pankaj Kulkarni,

50

Solo una nota: non dimenticare di abilitare l'interazione sulla vista:

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

view.addGestureRecognizer(tap)

// view.userInteractionEnabled = true

self.view.addSubview(view)

1
La nota è importante!
Itai Spector,

21

PASSO 1

@IBOutlet var viewTap: UIView!

PASSO 2

var tapGesture = UITapGestureRecognizer()

PASSO: 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
}

PASSO: 4

func myviewTapped(_ sender: UITapGestureRecognizer) {

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

PRODUZIONE

inserisci qui la descrizione dell'immagine


14

Implementazione del gesto del tocco

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

Chiama questa funzione quando viene riconosciuto il tocco.

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

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

11

Swift 4

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

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

8

Funziona così in 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")
}

7

Risposta completa per Swift 4

Passaggio 1: creare uno sbocco per la vista

@IBOutlet weak var rightViewOutlet: UIView!

Passaggio 2: definire un gesto di tocco

var tapGesture = UITapGestureRecognizer()

Passaggio 3: creare la funzione ObjC (chiamata quando si tocca la vista)

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

Passaggio 4: aggiungere quanto segue in viewDidLoad ()

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

Il passaggio 2 non è richiesto.
guido,

7

Swift 5.1 Esempio per tre viste

Passaggio: 1 -> Aggiungi vista storyboard e aggiungi vista outlet Controllo UIView

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

Passaggio: 2 -> Aggiungi tag visualizzazione storyBoard

FirstView secondView thirdView

Passaggio: 3 -> Aggiungi 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
    }

Passaggio: 4 -> seleziona 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")
        }
    }

6

Ho lavorato su Xcode 6.4 su swift. Vedi sotto.

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
}

5

Se desideri che il codice obiettivo C sia indicato di seguito,

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 vuoi che il codice rapido sia indicato di seguito,

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

5

Devi inizializzare UITapGestureRecognizer con un target e un'azione, in questo modo:

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

Quindi, è necessario implementare il gestore, che verrà chiamato ogni volta che si verifica un evento di tocco:

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

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

3

Swift 4

Innanzitutto, crea un oggetto di UITapGestureRecognizer

var tapGesture = UITapGestureRecognizer()

Il secondo passo è inizializzare UITapGestureReconizer. Abilita l'interazione dell'utente, quindi aggiungila.

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

Terzo, crea un metodo

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

3

prova la seguente estensione

    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
}

e poi usalo:

submitBtn.addTapGesture {
     //your code
}

puoi persino usarlo per cellulare

cell.addTapGesture {
     //your code
}

1
Mentre una risposta di solo codice è davvero una risposta, un po 'di spiegazione (perché il codice OP non ha funzionato, qual è l'idea generale alla base del codice, punti importanti, avvertenze, ...) potrebbe renderla una risposta migliore .
Lfurini,

2

Ho lavorato su Xcode 7.3.1 su Swift 2.2. Vedi sotto.

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

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

1
aggiungi addTapGesture()nel tuoviewDidLoad()
Daya Kevin il

1

Volevo specificare due punti che continuavano a causarmi problemi.

  • Stavo creando il Gesture Recognizer su init e lo memorizzavo in una proprietà let. Apparentemente, l'aggiunta di questo gesto alla vista non funziona. Può essere un oggetto auto passato al riconoscimento gesti durante init, non è configurato correttamente.
  • Il riconoscimento gesti non deve essere aggiunto alle viste con zero fotogrammi. Creo tutte le mie viste con frame zero e quindi le ridimensiono usando il layout automatico. I riconoscitori di gesti devono essere aggiunti DOPO che le viste sono state ridimensionate dal motore di autolayout. Quindi aggiungo il riconoscimento dei gesti in viewDidAppear e funzionano.

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

     }
}

La funzione onSelect non deve essere IBAction
Illya Krit

iView? .addGestureRecognizer (tocca) Il nome del tuo gestoRecognizer è clickUITapGestureRecognizer Quindi il modo giusto è: iView? .addGestureRecognizer (clickUITapGestureRecognizer)
Illya Krit

1

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

Scopo della chiamata

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

Scopo della posta

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

1

Ecco il modo più semplice per aggiungere gesti su View in 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")
        }
    }
}

0

Prova il seguente codice rapido (testato in 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);
        }
      }
    }

Nota che il tuo target potrebbe essere qualsiasi sottoclasse di UIResponder, vedi (testato in 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!)
      }
    }

0

Invece di invocare UITapGestureRecognizer di myView, puoi chiamare direttamente la handleTapfunzione,

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.