Jak wywołać gest, stuknij programowo UIView w szybki

166

Mam UIView i dodałem do niego gest stuknięcia:

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

Próbuję wywołać to programowo w pliku testowym.

sendActionForEvent

Używam tej funkcji, ale nie działa:

myView.sendActionForEvent(UIEvents.touchUpDown)

Pokazuje nierozpoznany selektor wysłany do instancji.

Jak mogę rozwiązać ten problem?

Jerzy
źródło
2
W swift 2.2 można użyć nowej składni selektora: niech kranu = UITapGestureRecognizer (cel: samodzielne działanie: #selector (self.handleTap (_ :)))
Wujo
@wujo - dzięki za to; dziwnie to tak naprawdę nie działa dla mnie, w UIView Może tylko w kontrolerze widoku?
Fattie
2
Pamiętaj również o tym, imageView.userInteractionEnabled = truejeśli używasz widoku obrazu. Za długo się tym złapałem.
Josh
@Josh, tak, ważna kwestia.
NeverHopeless
1
@KhangAzun najlepszą opcją jest bezpośrednie wywołanie funkcji tap
George

Odpowiedzi:

245

Musisz zainicjować UITapGestureRecognizercel i akcję, na przykład:

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

Następnie należy zaimplementować procedurę obsługi, która będzie wywoływana za każdym razem, gdy wystąpi zdarzenie tap:

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

Teraz wywołanie modułu obsługi zdarzeń rozpoznawania gestów dotknięcia jest tak proste, jak wywołanie metody:

handleTap()
Salavat Khanov
źródło
zamiast bezpośrednio wywoływać funkcję selektora, chcę ją wywołać, wywołując programowo zdarzenie UITapGestureRecognizer
George
2
@muhasturk Nie zmieniaj znaczenia odpowiedzi, za którą głosowano. Twoja zmiana unieważniała odpowiedź dla starszych wersji Swift. Jeśli chcesz opublikować aktualizację dla Swift 2.2, napisz własną odpowiedź. Dziękuję Ci.
Eric Aya
17
tap.delegate = selfnie jest potrzebne, ponieważ już wyznaczyłeś cel i akcję
Daniel
4
Zgłasza błąd w Swift3, twoja funkcja stukania uchwytu powinna wyglądać następująco: func handleTap (_ sender: UITapGestureRecognizer)
Travis M.
Funkcja wywołania powinna być ................ func handleTap (_ sender: UITapGestureRecognizer? = Nil) ............... przegapiłeś "_ "........ więc twoja funkcja dzwonienia nie działała ...
Prasad Patil
94

Dla każdego, kto szuka rozwiązania 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
źródło
1
isUserInteractionEnabledjest naprawdę konieczne? wartość domyślna to false?
jose920405
6
view.isUserInteractionEnabled = truejest kluczem, gdy twój widok to ImageView lub dowolna podklasa UIVIew zamiast UIControl.
Pankaj Kulkarni
61

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

W Swift 4 musisz wyraźnie wskazać, że wyzwalana funkcja jest wywoływana z Objective-C, więc musisz dodać @objc także do swojej funkcji handleTap.

Zobacz odpowiedź @Ali Beadle tutaj: Swift 4 dodaj gest: nadpisanie vs @objc

RNHTTR
źródło
view.isUserInteractionEnabled = truejest kluczem, gdy twój widok to ImageView lub dowolna podklasa UIVIew zamiast UIControl.
Pankaj Kulkarni
50

Tylko uwaga - nie zapomnij włączyć interakcji w widoku:

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

view.addGestureRecognizer(tap)

// view.userInteractionEnabled = true

self.view.addSubview(view)
eclewlow
źródło
1
Uwaga jest ważna!
Itai Spector
21

KROK 1

@IBOutlet var viewTap: UIView!

KROK 2

var tapGesture = UITapGestureRecognizer()

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

KROK 4

func myviewTapped(_ sender: UITapGestureRecognizer) {

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

WYNIK

wprowadź opis obrazu tutaj

Kirit Modi
źródło
14

Wdrażanie gestu stuknięcia

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

Wywołuje tę funkcję po rozpoznaniu kranu.

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

Aktualizacja dla 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
źródło
11

Szybki 4

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

@objc func touchTapped(_ sender: UITapGestureRecognizer) {
}
Giang
źródło
8

Tak to działa w 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
źródło
7

Pełna odpowiedź dla Swift 4

Krok 1: utwórz ujście dla widoku

@IBOutlet weak var rightViewOutlet: UIView!

Krok 2: zdefiniuj gest stuknięcia

var tapGesture = UITapGestureRecognizer()

Krok 3: Utwórz funkcję ObjC (wywoływaną po dotknięciu widoku)

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

Krok 4: Dodaj następujące elementy w ramach viewDidLoad ()

let rightTap = UITapGestureRecognizer(target: self, action: #selector(ViewController.rightViewTapped(_:)))
    rightViewOutlet.addGestureRecognizer(rightTap)
Jerzy
źródło
Krok 2 nie jest wymagany.
guido
7

Swift 5.1 Przykład trzech widoków

Krok: 1 -> Dodaj widok scenorysu i dodaj widok gniazdkaController UIView

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

Krok: 2 -> Dodaj tag widoku StoryBoard

firstView secondView thirdView

Krok: 3 -> Dodaj gest

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
    }

Krok: 4 -> wybierz widok

@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
źródło
6

Pracowałem na Xcode 6.4 na swift. Zobacz poniżej.

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
źródło
5

Jeśli chcesz, aby kod celu C podano poniżej,

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

lub chcesz, aby szybki kod podano poniżej,

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
źródło
5

Musisz zainicjować UITapGestureRecognizer z celem i akcją, na przykład:

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

Następnie należy zaimplementować procedurę obsługi, która będzie wywoływana za każdym razem, gdy wystąpi zdarzenie tap:

func handleTap(sender: UITapGestureRecognizer) {
  // handling code
}
Amit Raj Modi
źródło
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
źródło
3

Szybki 4

Najpierw utwórz obiekt UITapGestureRecognizer

var tapGesture = UITapGestureRecognizer()

Drugim krokiem jest zainicjowanie UITapGestureReconizer. Włącz interakcję z użytkownikiem, a następnie dodaj ją.

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

Po trzecie, utwórz metodę

@objc func myviewTapped(_ recognizer: UIGestureRecognizer) {
                print("button is tapped")
            }
Akbar Khan
źródło
3

wypróbuj następujące rozszerzenie

    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
}

a następnie użyj go:

submitBtn.addTapGesture {
     //your code
}

możesz go nawet użyć do komórki

cell.addTapGesture {
     //your code
}
mahdi delavar
źródło
1
Chociaż odpowiedź zawierająca tylko kod jest rzeczywiście odpowiedzią, trochę wyjaśnienia (dlaczego kod OP nie zadziałał, jaka jest ogólna idea twojego kodu, ważne punkty, ostrzeżenia, ...) może sprawić, że będzie to lepsza odpowiedź.
lfurini
2

Pracowałem nad Xcode 7.3.1 na Swift 2.2. Zobacz poniżej.

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
źródło
1
dodaj addTapGesture()swojeviewDidLoad()
Daya Kevin
1

Chciałem określić dwa punkty, które wciąż sprawiały mi problemy.

  • Tworzyłem Rozpoznawanie gestów na init i przechowywałem go we właściwości let. Najwyraźniej dodanie tego rozpoznanego gestu do widoku nie działa. Może to być obiekt własny przekazany do aparatu rozpoznawania gestów podczas inicjalizacji, nie jest poprawnie skonfigurowany.
  • Rozpoznawania gestów nie należy dodawać do widoków bez ramek. Tworzę wszystkie widoki z zerową ramką, a następnie zmieniam ich rozmiar za pomocą autolayout. Rozpoznawanie gestów należy dodać PO zmianie rozmiaru widoków przez silnik autoukładu. Więc dodaję rozpoznawanie gestów w viewDidAppear i działają.
nnrales
źródło
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
źródło
Funkcja onSelect nie musi być IBAction
Illya Krit
iView? .addGestureRecognizer (stuknij) Nazwa twojego gestuRecognizer to clickUITapGestureRecognizer Tak więc właściwa droga to: iView? .addGestureRecognizer (clickUITapGestureRecognizer)
Illya Krit
1

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

Cel wywołania

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

Cel poczty

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
źródło
1

Oto najprostszy sposób dodawania gestów w widoku w 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
źródło
0

Wypróbuj następujący szybki kod (przetestowany w 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);
        }
      }
    }

Zauważ, że twoim celem może być dowolna podklasa UIResponder, zobacz (testowane w 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
źródło
0

Zamiast wywoływać UITapGestureRecognizer myView, możesz bezpośrednio wywołać handleTapfunkcję,

budidino
źródło