dhaval shah
dhaval shah

Reputation: 4549

UIView touch event in controller

How can I add UIView touchbegin action or touchend action programmatically as Xcode is not providing from Main.storyboard?

Upvotes: 119

Views: 208298

Answers (11)

Rasoul Miri
Rasoul Miri

Reputation: 12232

You can use this way; create an extension.

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
}

and use this way:

@IBOutlet weak var testView: UIView!
testView.addTapGesture{
   // ...
}
    

Upvotes: 6

Miknash
Miknash

Reputation: 7948

You will have to add it through code. First, create the view and add it to the hierarchy:

var myView = UIView(frame: CGRectMake(100, 100, 100, 100))
self.view.addSubview(myView) 

After that initialize gesture recognizer. Until Swift 2:

let gesture = UITapGestureRecognizer(target: self, action: "someAction:")

After Swift 2:

let gesture = UITapGestureRecognizer(target: self, action:  #selector (self.someAction (_:)))

Then bind it to the view:

self.myView.addGestureRecognizer(gesture)

    

Swift 3:

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

Swift 4 just add @objc before func:

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

Swift UI:

Text("Tap me!").tapAction {
    print("Tapped!")
}

Upvotes: 173

ventuz
ventuz

Reputation: 1141

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
}

Upvotes: 103

iosdvlpr
iosdvlpr

Reputation: 595

Create outlets from views that were created in StoryBoard.

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

Override the touchesBegan method. There are 2 options, everyone can determine which one is better for him.

  1. Detect touch in special view.

    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. Detect touch point on special view.

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

Lastly, you need to declare the functions that will be called, depending on which view the user clicked.

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

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

func greenViewTapped() {
    print("greenViewTapped")
}

Upvotes: 9

Hiền Đỗ
Hiền Đỗ

Reputation: 546

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
 }

Upvotes: 6

Jacob Jidell
Jacob Jidell

Reputation: 2792

Updating @stevo.mit's answer for 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
    }
}

Upvotes: 2

DevB2F
DevB2F

Reputation: 5095

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

Upvotes: 9

stevo.mit
stevo.mit

Reputation: 4741

Updating @Crashalot's answer for 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
    }
}

Upvotes: 26

Pawan
Pawan

Reputation: 543

Just an update to above answers :

If you want to have see changes in the click event, i.e. Color of your UIVIew shud change whenever user clicks the UIView then make changes as below...

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

Also, call this Class from Storyboard & ViewController as:

@IBOutlet weak var panVerificationUIView:ClickableUIView!

Upvotes: 2

Crashalot
Crashalot

Reputation: 34523

Updating @Chackle's answer for 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
    }
}

Upvotes: 19

Chackle
Chackle

Reputation: 2269

Put this in your UIView subclass (it's easiest if you make a sublcass for this functionality).

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

Upvotes: 9

Related Questions