UIView Touch-Ereignis im Controller

93

Wie kann ich programmgesteuert UIView Touchbegin-Aktionen oder Touchend-Aktionen hinzufügen, da Xcode nicht über Main.storyboard bereitgestellt wird?

Dhaval Shah
quelle
Dieser ist für Knopf, das OP möchte Ereignis für UIView
Miknash
Verwenden Sie a UILongPressGestureRecognizermit der minimumPressDurationEinstellung auf Null. Siehe diese Antwort. Es ist nicht erforderlich, etwas zu unterordnen oder zu überschreiben.
Suragch

Antworten:

150

Sie müssen es durch Code hinzufügen. Versuche dies:

    // 1.create UIView programmetically
    var myView = UIView(frame: CGRectMake(100, 100, 100, 100))
    // 2.add myView to UIView hierarchy
    self.view.addSubview(myView) 
    // 3. add action to myView
    let gesture = UITapGestureRecognizer(target: self, action: "someAction:")
    // or for swift 2 +
    let gestureSwift2AndHigher = UITapGestureRecognizer(target: self, action:  #selector (self.someAction (_:)))
    self.myView.addGestureRecognizer(gesture)

    func someAction(sender:UITapGestureRecognizer){     
       // do other task
    }

    // or for Swift 3
    func someAction(_ sender:UITapGestureRecognizer){     
       // do other task
    }

    // or for Swift 4
    @objc func someAction(_ sender:UITapGestureRecognizer){     
       // do other task
    }

    // update for Swift UI

    Text("Tap me!")
        .tapAction {
             print("Tapped!")
        }
Miknash
quelle
1
Ich habe getan, dass es mir einen Fehler gibt, wenn ich auf die uiView klicke. Mein Code: let gesture = UITapGestureRecognizer (Ziel: self.uiPendingView, Aktion: "touchPending") self.uiPendingView.addGestureRecognizer (Geste) und Methode: func touchPending (Absender: AnyObject) {println ("METHOD >>>>>>> >>>>>>>>> ")}
dhaval shah
1
füge einfach hinzu: in "touchPending:" und in der Funktion sieht es aus wie func touchPending (Absender: UITapGestureRecognizer)
Rizwan Shaikh
1
Sie vermissen ':' in Aktion.
Miknash
Hallo, wie kann ich unterscheiden, auf welche UIView geklickt wurde, wenn alle dieselbe someAction-Funktion haben?
C Williams
Am einfachsten wäre es, die Tag-Eigenschaft zu verwenden und dann in der Funktion zu bestimmen, welche Ansicht der Absender ist
Miknash
65

Swift 4/5:

let gesture = UITapGestureRecognizer(target: self, action:  #selector(self.checkAction))
self.myView.addGestureRecognizer(gesture)

@objc func checkAction(sender : UITapGestureRecognizer) {
    // Do what you want
}

Swift 3:

let gesture = UITapGestureRecognizer(target: self, action:  #selector(self.checkAction(sender:)))
self.myView.addGestureRecognizer(gesture)

func checkAction(sender : UITapGestureRecognizer) {
    // Do what you want
}
ventuz
quelle
3
ERSTE 2 LINIEN SOLLTEN VON VIEWDIDLOAD AUFRUFEN!
Oleksandr
23

Aktualisierung der Antwort von @ Crashalot für Swift 3.x:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.location(in: self)
        // do something with your currentPoint
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.location(in: self)
        // do something with your currentPoint
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.location(in: self)
        // do something with your currentPoint
    }
}
stevo.mit
quelle
17

Aktualisierung der Antwort von @ Chackle für Swift 2.x:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.locationInView(self)
        // do something with your currentPoint
    }
}

override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.locationInView(self)
        // do something with your currentPoint
    }
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.locationInView(self)
        // do something with your currentPoint
    }
}
Crashalot
quelle
7

UIViewFügen Sie dies in Ihre Unterklasse ein (es ist am einfachsten, wenn Sie eine Unterklasse für diese Funktionalität erstellen).

class YourView: UIView {

  //Define your initialisers here

  override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
    if let touch = touches.first as? UITouch {
      let currentPoint = touch.locationInView(self)
      // do something with your currentPoint
    }
  }

  override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
    if let touch = touches.first as? UITouch {
      let currentPoint = touch.locationInView(self)
      // do something with your currentPoint
    }
  }

  override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
    if let touch = touches.first as? UITouch {
      let currentPoint = touch.locationInView(self)
      // do something with your currentPoint
    }
  }
}
Chackle
quelle
@Chacle, ich habe mehr als 10 Uiview auf meiner Seite und möchte in einigen von Sub UIView Aktionen hinzufügen. Also, was soll ich dafür ändern?
Dhaval Shah
Es hängt davon ab, wofür Sie es verwenden möchten. Möchten Sie sagen, welche UIViewSie drücken, oder möchten Sie einige Druckmaschinen in jeder der Tasten handhaben UIView?
Chackle
Ich möchte nur für eine bestimmte UI-Ansicht suchen.
Dhaval Shah
6

Für schnelle 4

@IBOutlet weak var someView: UIView!  
let gesture = UITapGestureRecognizer(target: self, action:  #selector (self.someAction (_:)))
self.someView.addGestureRecognizer(gesture)

@objc func someAction(_ sender:UITapGestureRecognizer){
    print("view was clicked")
}
DevB2F
quelle
4

Swift 4.2:

@IBOutlet weak var viewLabel1: UIView!
@IBOutlet weak var viewLabel2: UIView!
  override func viewDidLoad() {
    super.viewDidLoad()

    let myView = UITapGestureRecognizer(target: self, action: #selector(someAction(_:)))
    self.viewLabel1.addGestureRecognizer(myView)
}

 @objc func someAction(_ sender:UITapGestureRecognizer){
   viewLabel2.isHidden = true
 }
Hiền Đỗ
quelle
4

Erstellen Sie Outlets aus Ansichten, die in StoryBoard erstellt wurden.

@IBOutlet weak var redView: UIView!
@IBOutlet weak var orangeView: UIView!
@IBOutlet weak var greenView: UIView!   

Überschreiben Sie die touchBegan-Methode. Es gibt 2 Möglichkeiten, jeder kann bestimmen, welche für ihn besser ist.

  1. Berührung in spezieller Ansicht erkennen.

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
         if let touch = touches.first {
            if touch.view == self.redView {
                tapOnredViewTapped()
            } else if touch.view == self.orangeView {
                orangeViewTapped()
            } else if touch.view == self.greenView {
                greenViewTapped()
            } else {
                return
            }
        }
    
    }
  2. Berührungspunkt in einer speziellen Ansicht erkennen.

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let touch = touches.first {
            let location = touch.location(in: view)
            if redView.frame.contains(location) {
                redViewTapped()
            } else if orangeView.frame.contains(location) {
                orangeViewTapped()
            } else if greenView.frame.contains(location) {
                greenViewTapped()
            }
        }
    
    }

Zuletzt müssen Sie die Funktionen deklarieren, die aufgerufen werden, je nachdem, auf welche Ansicht der Benutzer geklickt hat.

func redViewTapped() {
    print("redViewTapped")
}

func orangeViewTapped() {
    print("orangeViewTapped")
}

func greenViewTapped() {
    print("greenViewTapped")
}
iAleksandr
quelle
Sehr gut, tolles Beispiel, danke, dass du es mir gezeigt hast !! dass wir dies auch mit touchEvent tun können .. ich kenne nur Zwei-Wege-Taste und Geste .. Danke +1
Yogesh Patel
3

Sie können Folgendes verwenden: Erweiterung erstellen

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
}

und benutze diesen Weg:

@IBOutlet weak var testView: UIView!
testView.addTapGesture{
   // ...
}
Rasoul Miri
quelle
1

Nur ein Update zu den obigen Antworten:

Wenn Sie Änderungen im Klickereignis sehen möchten, dh die Farbe Ihres UIVIew-Shud ändert sich, wenn der Benutzer auf die UIView klickt, und nehmen Sie die folgenden Änderungen vor ...

class ClickableUIView: UIView {
    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
            if let touch = touches.first {
                let currentPoint = touch.locationInView(self)
                // do something with your currentPoint
            }

            self.backgroundColor = UIColor.magentaColor()//Color when UIView is clicked.
        }

        override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
            if let touch = touches.first {
                let currentPoint = touch.locationInView(self)
                // do something with your currentPoint
            }

            self.backgroundColor = UIColor.magentaColor()//Color when UIView is clicked.
        }

        override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
            if let touch = touches.first {
                let currentPoint = touch.locationInView(self)
                // do something with your currentPoint
            }

            self.backgroundColor = UIColor.whiteColor()//Color when UIView is not clicked.

}//class closes here

Rufen Sie diese Klasse in Storyboard & ViewController außerdem wie folgt auf:

@IBOutlet weak var panVerificationUIView:ClickableUIView!
Pawan
quelle
1

Aktualisierung der Antwort von @ stevo.mit für Swift 4.x:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.location(in: self.view)
        // do something with your currentPoint
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.location(in: self.view)
        // do something with your currentPoint
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let currentPoint = touch.location(in: self.view)
        // do something with your currentPoint
    }
}
Jacob Ahlberg
quelle