I am new to swift (and Xcode development in general) and I was wondering how to make an ImageView on the storyboard clickable. What I'm trying to do is make it so when its clicked, it shows another view controller.
-
check this out http://stackoverflow.com/a/27235390/3810673 – Ian Mar 23 '15 at 04:02
9 Answers
You can add tapGesture for that. Here is the code:
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// create tap gesture recognizer
let tapGesture = UITapGestureRecognizer(target: self, action: "imageTapped:")
// add it to the image view;
imageView.addGestureRecognizer(tapGesture)
// make sure imageView can be interacted with by user
imageView.userInteractionEnabled = true
}
func imageTapped(gesture: UIGestureRecognizer) {
// if the tapped view is a UIImageView then set it to imageview
if let imageView = gesture.view as? UIImageView {
println("Image Tapped")
//Here you can initiate your new ViewController
}
}
}
Swift 3.0
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// create tap gesture recognizer
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.imageTapped(gesture:)))
// add it to the image view;
imageView.addGestureRecognizer(tapGesture)
// make sure imageView can be interacted with by user
imageView.isUserInteractionEnabled = true
}
func imageTapped(gesture: UIGestureRecognizer) {
// if the tapped view is a UIImageView then set it to imageview
if (gesture.view as? UIImageView) != nil {
print("Image Tapped")
//Here you can initiate your new ViewController
}
}
}
Swift 5.0
class ViewController: UIViewController {
@IBOutlet weak var imageView: UIImageView!
override func viewDidLoad() {
super.viewDidLoad()
// create tap gesture recognizer
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(ViewController.imageTapped(gesture:)))
// add it to the image view;
imageView.addGestureRecognizer(tapGesture)
// make sure imageView can be interacted with by user
imageView.isUserInteractionEnabled = true
}
@objc func imageTapped(gesture: UIGestureRecognizer) {
// if the tapped view is a UIImageView then set it to imageview
if (gesture.view as? UIImageView) != nil {
print("Image Tapped")
//Here you can initiate your new ViewController
}
}
}

- 71,228
- 33
- 160
- 165
-
9While this is a possibility, it is much better to create a `UIButton` with an image than making an image clickable. When adding accessibility options, you will thank me. – vrwim Mar 23 '15 at 14:44
You can do it even easier and make a image clickable via Storyboard with no coding at all.
- First you need to drag a
UITapGestureRecognizer
onto yourUIImageView
in Storyboard. - Then you create the IBAction you want to run in your code with
@IBAction func imageClicked(_ sender: Any) {}
- Next you need to connect the
UITapGestureRecognizer
to theIBAction
in your class by selecting the gesture recognizer in theDocument Outline
, then switching to theConnection Inspector Tab
and dragging theSent Actions
->Selector
to yourUIViewController
where you then select the appropriate action you created previously. - Finally you have to set the checkbox
User Interaction Enabled
on the image view on both the Identity Inspector and on the Attributes Inspector.
Done, a fully clickable UIImageView without writing a single line of code except the obvious function you want to invoke. But hey, if you for example want to push a segue instead, then you can go without coding at all by using the gesture recognizers Triggered Segues
instead of its Sent Actions
.
Though Storyboard have their limitations, theres no need to write code for clickable images. ;)

- 14,425
- 24
- 101
- 194

- 6,175
- 2
- 31
- 50
-
-
-
2Even though I checked 'User Interaction Enabled' in Identity Inspector, I had to explicitly set: `fooImage.isUserInteractionEnabled = true` in `viewDidLoad()` to make it work (Xcode bug ? or what? I don't know) – MD TAREQ HASSAN Jan 28 '20 at 02:07
-
2@HassanTareq Please set 'User Interaction Enabled' both on the Identity Inspector, and on the Attributes Inspector; works for me. – Giorgio Barchiesi May 13 '20 at 13:48
I would suggest creating a UIButton with no text and making it the image you want, instead. After doing that, you can CTRL-drag from the image to the view controller you want to segue to. Or you can just make an IBAction in your view controller's code that manually segues.

- 699
- 6
- 11
-
This works quite well. You can configure the UIImageView that's embedded in the button, too. It avoids the blended layer issue that the old trick of overlaying a UIImageView with a transparent button had. – Bob Wakefield Sep 14 '16 at 17:04
for swift version 3.0 try below code
override func viewDidLoad() {
super.viewDidLoad()
let tap1 = UITapGestureRecognizer(target: self, action: #selector(tapGesture1))
imageview.addGestureRecognizer(tap1)
imageview.isUserInteractionEnabled = true
}
func tapGesture1() {
print("Image Tapped")
}

- 2,327
- 1
- 16
- 19
On the storyboard set image view user interaction enabled and then get with this method
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
if ([touch view] == yourImageView)
{
//add your code for image touch here
}
}

- 1,993
- 25
- 36

- 18,888
- 9
- 57
- 72
Firstly, created one image view. Than write this code override func viewDidLoad() { super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(tapGesture))
imageview.addGestureRecognizer(tap)
imageview.isUserInteractionEnabled = true
}
func tapGesture() {
print("Image View Tapped")
}
in your view controller.
UITapGestureRecognizer method do everything is clickable

- 131
- 4
I achieved this by setting user interaction enable = true
and this code below in TouchesBegan... Clean and simple for this
ImageView was also inside a StackView
if let touch = touches.first {
if touch.view == profilePicture {
print("image touched")
}
}

- 4,177
- 11
- 45
- 65

- 92
- 2
- 9
Well, although you can use a UITapGestureRecognizer like mentioned above, if you need to do a quick project and just care about the functionality of the app, the easiest way is to have a transparent button covering your UIImageView with no text, and then using that to write whatever code you want. Sure, this will not be recommended if you're making a very important project or something but if you just want to make a quick app (let's say a very simple MVP for some meeting) this method should work fine.

- 11
- 1
in my opinion the reasonable way is to create extension of UIImage...
This is the code i found...
public typealias SimpleClosure = (() -> ())
private var tappableKey : UInt8 = 0
private var actionKey : UInt8 = 1
extension UIImageView {
@objc var callback: SimpleClosure {
get {
return objc_getAssociatedObject(self, &actionKey) as! SimpleClosure
}
set {
objc_setAssociatedObject(self, &actionKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
}
}
var gesture: UITapGestureRecognizer {
get {
return UITapGestureRecognizer(target: self, action: #selector(tapped))
}
}
var tappable: Bool! {
get {
return objc_getAssociatedObject(self, &tappableKey) as? Bool
}
set(newValue) {
objc_setAssociatedObject(self, &tappableKey, newValue, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN)
self.addTapGesture()
}
}
fileprivate func addTapGesture() {
if (self.tappable) {
self.gesture.numberOfTapsRequired = 1
self.isUserInteractionEnabled = true
self.addGestureRecognizer(gesture)
}
}
@objc private func tapped() {
callback()
}
}
and usage should look like
@IBOutlet weak var exampleImageView: UIImageView! {
didSet {
self.exampleImageView.tappable = true
}
}override func viewDidLoad() {
super.viewDidLoad()
self.exampleImageView.callback = {
//TODO: Here you put the On click code.
}
}

- 101
- 1
- 2