Comment appeler le geste tap sur UIView par programmation dans Swift


167

J'ai un UIView et j'y ai ajouté un geste de tapotement:

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

J'essaye de l'appeler par programme dans le fichier de test.

sendActionForEvent

J'utilise cette fonction, mais cela ne fonctionne pas:

myView.sendActionForEvent(UIEvents.touchUpDown)

Il montre un sélecteur non reconnu envoyé à l'instance.

Comment puis-je résoudre ce problème?


2
Dans swift 2.2, vous pouvez utiliser une nouvelle syntaxe de sélecteur: let tap = UITapGestureRecognizer (target: self, action: #selector (self.handleTap (_ :)))
Wujo

@wujo - merci pour cela; étrangement cela ne fonctionne pas pour moi, dans un UIView Peut-être seulement dans un contrôleur de vue?
Fattie

2
N'oubliez pas de l'avoir imageView.userInteractionEnabled = truesi vous utilisez une vue d'image. Je suis tombé dessus pendant trop longtemps.
Josh

@Josh, oui un point important.
NeverHopeless

1
@KhangAzun la meilleure option est d'appeler directement la fonction tap
George

Réponses:


246

Vous devez initialiser UITapGestureRecognizeravec une cible et une action, comme ceci:

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

Ensuite, vous devez implémenter le gestionnaire, qui sera appelé à chaque fois qu'un événement tap se produit:

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

Alors maintenant, appeler votre gestionnaire d'événement de reconnaissance de geste tap est aussi simple que d'appeler une méthode:

handleTap()

au lieu d'appeler directement la fonction de sélection, je veux l'appeler en invoquant par programme l'événement UITapGestureRecognizer
George

2
@muhasturk Ne changez pas la signification d'une réponse votée. Votre modification invalide la réponse pour les anciennes versions de Swift. Si vous souhaitez publier une mise à jour pour Swift 2.2, postez votre propre réponse. Je vous remercie.
Eric Aya

17
tap.delegate = selfn'est pas nécessaire, puisque vous avez déjà défini un objectif et une action
Daniel

4
Lève une erreur dans Swift3, votre fonction de prise en main doit être: func handleTap (_ sender: UITapGestureRecognizer)
Travis M.

La fonction d'appel doit être ................ func handleTap (_ sender: UITapGestureRecognizer? = Nil) ............... vous avez manqué "_ "........ donc votre fonction d'appel ne fonctionnait pas ..
Prasad Patil

94

Pour tous ceux qui recherchent la 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
 func handleTap(_ sender: UITapGestureRecognizer) {
     print("Hello World")
  }

1
isUserInteractionEnabledest vraiment nécessaire? Le défaut est faux?
jose920405

6
view.isUserInteractionEnabled = trueest la clé lorsque votre vue est ImageView ou une sous-classe de UIVIew au lieu de UIControl.
Pankaj Kulkarni

61

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

Dans Swift 4, vous devez indiquer explicitement que la fonction déclenchée peut être appelée depuis Objective-C, vous devez donc également ajouter @objc à votre fonction handleTap.

Voir la réponse de @Ali Beadle ici: Swift 4 add gesture: override vs @objc


view.isUserInteractionEnabled = trueest la clé lorsque votre vue est ImageView ou une sous-classe de UIVIew au lieu de UIControl.
Pankaj Kulkarni

50

Juste une note - N'oubliez pas d'activer l'interaction sur la vue:

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

view.addGestureRecognizer(tap)

// view.userInteractionEnabled = true

self.view.addSubview(view)

1
La note est importante!
Itai Spector

21

ÉTAPE 1

@IBOutlet var viewTap: UIView!

ÉTAPE 2

var tapGesture = UITapGestureRecognizer()

ÉTAPE 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
}

ÉTAPE 4

func myviewTapped(_ sender: UITapGestureRecognizer) {

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

PRODUCTION

entrez la description de l'image ici


14

Implémentation du geste tap

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

Appelle cette fonction lorsque le robinet est reconnu.

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

Mise à jour pour 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

Voici comment cela fonctionne dans 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

Réponse complète pour Swift 4

Étape 1: créer une sortie pour la vue

@IBOutlet weak var rightViewOutlet: UIView!

Étape 2: définir un geste de toucher

var tapGesture = UITapGestureRecognizer()

Étape 3: créer la fonction ObjC (appelée lorsque la vue est appuyée)

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

Étape 4: ajoutez ce qui suit dans viewDidLoad ()

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

L'étape 2 n'est pas requise.
guido

7

Swift 5.1 Exemple pour trois vues

Étape: 1 -> Ajouter une vue de storyboard et ajouter une vue de sortie

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

Étape: 2 -> Ajouter un tag de vue storyBoard

firstView secondView ThirdView

Étape: 3 -> Ajouter un geste

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
    }

Étape: 4 -> sélectionnez la vue

@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

J'ai travaillé sur Xcode 6.4 sur swift. Voir ci-dessous.

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

Si vous voulez que le code Objective C soit donné ci-dessous,

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

ou vous voulez que le code swift soit donné ci-dessous,

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

Vous devez initialiser UITapGestureRecognizer avec une cible et une action, comme ceci:

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

Ensuite, vous devez implémenter le gestionnaire, qui sera appelé à chaque fois qu'un événement tap se produit:

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

Tout d'abord, créez un objet de UITapGestureRecognizer

var tapGesture = UITapGestureRecognizer()

La deuxième étape consiste à initialiser UITapGestureReconizer. Activez l'interaction utilisateur, puis ajoutez-la.

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

Troisièmement, créez une méthode

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

3

essayez l'extension suivante

    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
}

puis utilisez-le:

submitBtn.addTapGesture {
     //your code
}

vous pouvez même l'utiliser pour la cellule

cell.addTapGesture {
     //your code
}

1
Alors qu'une réponse en code seul est en effet une réponse, un peu d'explication (pourquoi le code de l'OP n'a pas fonctionné, quelle est l'idée générale derrière votre code, points importants, avertissements, ...) pourrait en faire une meilleure réponse.
lfurini

2

J'ai travaillé sur Xcode 7.3.1 sur Swift 2.2. Voir ci-dessous.

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

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

1
ajouter addTapGesture()dans votreviewDidLoad()
Daya Kevin

1

Je voulais préciser deux points qui me posaient des problèmes.

  • J'étais en train de créer le Gesture Recognizer sur init et de le stocker dans une propriété let. Apparemment, l'ajout de cette reconnaissance de geste à la vue ne fonctionne pas. Peut-être que l'objet self est transmis au module de reconnaissance de mouvement lors de l'initialisation, n'est pas correctement configuré.
  • Le module de reconnaissance de mouvement ne doit pas être ajouté aux vues avec zéro image. Je crée toutes mes vues avec zéro image, puis je les redimensionne à l'aide de la mise en page automatique. Les outils de reconnaissance de gestes doivent être ajoutés APRÈS que les vues aient été redimensionnées par le moteur de mise en page automatique. J'ajoute donc le logiciel de reconnaissance de gestes dans viewDidAppear et ils fonctionnent.

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 fonction onSelect n'a pas besoin d'être IBAction
Illya Krit

iView? .addGestureRecognizer (appuyez) Le nom de votre gestureRecognizer est clickUITapGestureRecognizer La bonne façon est donc: iView? .addGestureRecognizer (clickUITapGestureRecognizer)
Illya Krit

1

Vue intérieureDidLoad

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

Objectif de l'appel

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

Objet du courrier

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

Voici le moyen le plus simple d'ajouter des gestes sur la vue dans 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

Essayez le code Swift suivant (testé dans 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);
        }
      }
    }

Notez que votre cible peut être n'importe quelle sous-classe de UIResponder, voir (testé dans 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

Au lieu d'appeler UITapGestureRecognizer de myView, vous pouvez appeler directement la handleTapfonction,

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.