I have a small issue that I couldn't fix for a few hours now! I have a simple ViewController with a label, which is linked to my ViewController class. I also set up an UIGestureRecognizer to change the text of the label when the label is clicked. But weirdly nothing happens at all.
The text of the label changes from whatever is set in the Storyboard to "Hello", so the setup is correct. But when I click the label, nothing happens.
Here's the entire ViewController class:
import UIKit
class PremiumViewController: UIViewController {
// Views
#IBOutlet weak var premiumLabel: UILabel!
// View Did Load
override func viewDidLoad() {
super.viewDidLoad()
premiumLabel.text = "Hello"
// Tap listener
let tap = UIGestureRecognizer(target: self, action: #selector(PremiumViewController.clicked))
premiumLabel.isUserInteractionEnabled = true
premiumLabel.addGestureRecognizer(tap)
}
#objc func clicked() {
premiumLabel.text = "You clicked me"
}
}
Use UITapGestureRecognizer instead of UIGestureRecognizer
change from
let tap = UIGestureRecognizer(target: self, action: #selector(PremiumViewController.clicked))
to
let tap = UITapGestureRecognizer(target: self, action: #selector(PremiumViewController.clicked))
Related
I'm building an application in Swift 3, so I want to call a function if I click on a particular UILabel, so I'm write this code but not works:
let tap = UITapGestureRecognizer(target: self, action: #selector(ViewController.tapFunction))
self.labelTemp.isUserInteractionEnabled = true
self.labelTemp.addGestureRecognizer(tap)
How can I render UILabel clickable ?
Set user interaction enabled for the UILabel and add the below code in the viewDidLoad()
self.label.isUserInteractionEnabled = true
let tap = UITapGestureRecognizer(target: self, action: #selector(self.labelTapped))
self.label.addGestureRecognizer(tap)
Add the tap action function as below :
#objc func labelTapped(_ gestureRecognizer: UITapGestureRecognizer) {
print("Label clicked")
}
Please make user that there is no other transparent view overlapping the UILabel in the view. If the UILabel is a part of another view then please make sure that the container View's user interaction is enabled.
Hope this helps.
Your selector should be an #objc func within self.
<#YourLabel#>.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.handleLabelTap)))
And when the user taps the label it will trigger:
#objc func handleLabelTap() {
// handle label tap here
}
You are lacking a function to trigger when the gesture touch is recognized. You need to add following:
let tap = UITapGestureRecognizer(target: self, action: #selector(tapFunction(_:)))
self.labelTemp.isUserInteractionEnabled = true
self.labelTemp.addGestureRecognizer(tap)
#objc func tapFunction(_ gestureRecognizer: UITapGestureRecognizer) {
// handle label tap here
}
Please ensure that You have connected the outlet to UILabel because I have created simple demo code by copy-paste your code and it is worked as expected.
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(tapFunction))
self.labelTemp.isUserInteractionEnabled = true
self.labelTemp.addGestureRecognizer(tap)
}
#objc func tapFunction() {
print("tapFunction")
}
I suggest, Please remove UILabel from UIViewController and add it again.
Download sample code
Note: - Please ensure that user-interaction of UILabelis enabled
First you need to add Tap Gesture into storyboard
Create Action of that particular gesture
override func viewDidLoad() {
super.viewDidLoad()
let tapOnLabel = UITapGestureRecognizer(target: self, action: #selector(self.tapGestireAction))
self.labelTemp.isUserInteractionEnabled = true
self.labelTemp.addGestureRecognizer(tapOnLabel)
}
#IBAction func tapGestureAction(_ sender: UITapGestureRecognizer) {
//Perform action
}
This question already has answers here:
How do you make an UIImageView on the storyboard clickable (swift)
(9 answers)
Closed 4 years ago.
I am trying to use a custom image as a button in my app. How do I add an action for an image?
This is for an iOS app and I don't want to use the default text button as a button. I've already tried control+dragging the image to the ViewController but there is no "Action" option.
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
let designChoice = designPrac.randomElement()
let forChoice = forWhatPrac.randomElement()
let helpChoice = toHelpPrac.randomElement()
designLabel.text = designChoice
forLabel.text = forChoice
helpLabel.text = helpChoice
}
This is the code I have to run when the app launches but I can't find a way to get this to work for when my image button is clicked.
In order to add an action to an UIImageView, you need to add a UITapGestureRecognizer to it, you can do it like this:
<#YourImageView#>.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.handleImageTap)))
Then you can handle the tap using the selector:
#objc func handleImageTap() {
// handle image tap here
}
You can use addGestureRecognizer for this purpose:
let imageView = UIImageView()
//add necessary code
imageView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(MethodForAction)))
According to How do you make an UIImageView on the storyboard clickable (swift):
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
}
}
I am working with a series of views stored in an outlet collection.
#IBOutlet var theViews: [UIView]!
In my viewDidLoad function I am looping over the collection of views during which I create a UITapGestureRecognizer and add it to the view.
for v in theViews {
let tap = UITapGestureRecognizer(target: self, action: #selector(self.flipSingleView(sender:)))
tap.delegate = self
tap.numberOfTapsRequired = 1
tap.numberOfTouchesRequired = 1
v.addGestureRecognizer(tap)
v.isUserInteractionEnabled = true
}
Here is the function that the selector points to:
#objc func flipSingleView(sender: UITapGestureRecognizer) {
print("tapped")
}
Additional notes:
User interaction is enabled for these views
Breakpoint inside flipSingleView is never reached
The View Controller implements UIGestureRecognizerDelegate (I've looked through the protocol and don't see a function that would be useful in this situation)
Have Verified that all views in question have outlet connections to the outlet collection
Nothing prints to the console
You mentioned your views are in an outlet collection, so I'm assuming it looks something like this:
#IBOutlet var myViews: [UIView]!
Not sure you need everything you threw in there. Try this:
// In viewDidLoad
myViews.forEach{ view in
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(gesture:)))
tap.numberOfTapsRequired = 1
tap.delegate = self
view.addGestureRecognizer(tap)
}
For your handler:
#objc func handleTap(gesture: UIGestureRecognizer) {
print("tap")
}
And lastly, put in a section for delegate methods, even if it's just empty:
extension ViewController: UIGestureRecognizerDelegate {
// TODO: Fill in as needed
}
To figure out which view sent it, you could add a tag to the view.
first post so apologies if I mess something up. I have researched this for hours upon hours and read other posts here on stack exchange to no avail.
I have created a nib file that defines a custom view and have defined a custom class (UIView) to manage the outlets of the custom view. As you can see from the code below excerpted from my custom UIView class associated with the nib, I have a date picker as the input view for the custom class and a UIToolBar with two UIBarButtonItems. Both of these appear as desired through a tap gesture recognizer... however the problem is the UIBarButtonItems do not call the action when tapped. Placing a breakpoint in the action function reveals that the code is never run. I feel that something with the view lifecycle is preventing a reference from being made, but I am new to Swift so some help here would be appreciated. I don't think it is selector syntax as the tap gesture recognizer works as desired. I've tried messing with button click handling access levels. I've tried doing input view setup when the view awakes from the nib as well, along with trying to put the code in different parts of the lifecycle.
If it matters for lifecycle's sake, this nib is a part of a table view cell. I call for this nib to be loaded when the table view cell awakes from it's nib.
Thanks!
#IBOutlet weak var timerStackView: UIStackView!{
didSet{
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(HandleTap(_:)))
timerStackView.addGestureRecognizer(tapGesture)
}
}
var datePicker: UIDatePicker {
let picker = UIDatePicker()
picker.backgroundColor = UIColor.black
picker.isOpaque = false
picker.setValue(UIColor.white, forKey: "textColor")
return picker
}
var datePickerAccessoryView: UIToolbar {
let accessoryView = UIToolbar()
let doneButton = UIBarButtonItem(title: "Done", style: UIBarButtonItemStyle.done, target: self, action: #selector(handleDatePickerButtonClick(_:)))
doneButton.tintColor = UIColor.white
let cancelButton = UIBarButtonItem(title: "Cancel", style: UIBarButtonItemStyle.plain, target: self, action: #selector(handleDatePickerButtonClick(_:)))
cancelButton.tintColor = UIColor.white
accessoryView.setItems([cancelButton, doneButton], animated: true)
return accessoryView
}
override var inputView: UIView? {return datePicker}
override var inputAccessoryView: UIView? {return datePickerAccessoryView}
override var canBecomeFirstResponder: Bool {return true}
override var canResignFirstResponder: Bool {return true}
// MARK: - Private functions
#objc fileprivate func HandleTap(_ sender: UITapGestureRecognizer) -> Void {
if !self.isFirstResponder {
switch sender.state {
case .ended:
datePicker.date = Date()
self.becomeFirstResponder()
default:
break
}
}
}
#objc #IBAction internal func handleDatePickerButtonClick(_ sender: UIBarButtonItem) -> Void {
switch sender.title! {
case "Done":
// To be implemented
case "Cancel":
// To be implemented
default:
break
}
}
You are initialising the UIToolbar without a frame and that would make it not register any touch events because they would be out of the toolbar's bounds.
Replace let accessoryView = UIToolbar() with something like let accessoryView = UIToolbar(frame: CGRect(x: 0, y: 0, width: view.bounds.width, height: 44))
Or you can call accessoryView.sizeToFit() before return accessoryView
I suppose the tap gesture recognizer is interfering with native UIBarButtonItem click events. But why do you use a gesture recognizer for that?
You should better add an action to each particular UIBarButtonItem.
I am very new to swift. I am implementing the functionality for click event for UIIMageview. My Code is below.
override func viewDidLoad() {
super.viewDidLoad()
initialize()
let logout = UIImage(named: "logout.png")
let location = UIImage(named:"location.png")
let appIcon = UIImage(named: "logo.png")
imgLogout.image = logout
imgLocation.image = location
appicon.image = appIcon
// Do any additional setup after loading the view, typically from a nib.
imgLogout.isUserInteractionEnabled = true
let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ProductListController.profileImageHasBeenTapped(gesture:)))
//this is where we add the target, since our method to track the taps is in this class
//we can just type "self", and then put our method name in quotes for the action parameter
//finally, this is where we add the gesture recognizer, so it actually functions correctly
imgLogout.addGestureRecognizer(tapGestureRecognizer)
}
func profileImageHasBeenTapped(gesture: UIGestureRecognizer){
print("Triggered")
}
my click event is not triggered. Any body can help me from this.
Any will be appreciated.
XCode version is 8.3.3
Swift version is 3.1
Why not using a UIButton, that is designed for that kind of usage ?
let logout = UIButton(type: .custom)
logout.setImage(UIImage(named: "logout.png"), forState: .normal)
logout.addTarget(self, action: #selector(self.performLogout), for: .touchUpInside)
#objc
func performLogout() {
// Do something
}
It seems like yourchildview not in the front so try it:
yourparentview.bringSubview(toFront: imgLogout)
imageLogOut frame may be out of super view's bounds, please check it.use
self.profileImageHasBeenTapped(gesture:)
instead of
ProductListController.profileImageHasBeenTapped(gesture:)
set user interaction enabled for the image.
// for creating tap gesture recognizer
#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
//if tap is not working bring image to front view
self.view.bringSubview(imageView)
}
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
}
}
}