UITapGestureRecognizer on custom table view cell doesn't work - ios

I'm trying to add a gesture recognizer for an image in a custom table view cell. For some reason I can't seem to make it work though. Here's my code
override func awakeFromNib() {
super.awakeFromNib()
heartImage.userInteractionEnabled = true
let gesture = UITapGestureRecognizer(target: self, action:Selector("onHeartTap"))
gesture.delegate = self
heartImage.addGestureRecognizer(gesture)
}
func onHeartTap(sender: UITapGestureRecognizer)
print("TAPPED")
}
The function awakeFromNib() gets called correctly, but onHeartTap() never gets called when tapping the image. What am I doing wrong?

User interaction was enabled for the image but not for the cell.
Enabled it for the cell from the storyboard and everything works. Thanks for the help everybody!

In your selector name 'onHeartTap' ":" is missing
just replace
let gesture = UITapGestureRecognizer(target: self, action:Selector("onHeartTap"))
with
let gesture = UITapGestureRecognizer(target: self, action:Selector("onHeartTap:"))
And also any specific reason you are doing this in awakeFromNib?? You can do this on viewWillAppear also.

I had a similar problem, that a UIImageView in a UITableViewCell subclass would not trigger the gesture recognizer that I set up.
func viewDidLoad() {
imageView.addGestureRecognizer(UIGestureRecognizer(target: self, action: #selector(imageViewTapped(sender:))))
imageView.isUserInteractionEnabled = true
}
the problem was the viewDidLoad() is not called for UITableViewCell:
Can I use viewDidLoad method in UITableviewCell?
set the gesture recognizer in awakeFromNib() instead:
override func awakeFromNib() {
imageView.addGestureRecognizer(UIGestureRecognizer(target: self, action: #selector(imageViewTapped(sender:))))
imageView.isUserInteractionEnabled = true
}

Related

UILabel set onClick

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
}

MessageKit : Add Gesture recognizer to messageCollectionView and cellDelegate doesn't work

I am using messageKit show messages,video and photo in a text format and all the messages are predefined. When user taps on the screen it, should show the next message. I have added gesture recognizer to messageCollectionView but when the user taps on the image, i need to show the image in full screen. But the cell delegate is never called
let gesture = UITapGestureRecognizer(target: self, action: #selector(MessageViewController.tapScreen(_:)))
messagesCollectionView.addGestureRecognizer(gesture)
messagesCollectionView.messagesDataSource = self
messagesCollectionView.messagesLayoutDelegate = self
messagesCollectionView.messagesDisplayDelegate = self
messagesCollectionView.messageCellDelegate = self
I am using the lates messageKit
pod 'MessageKit'
Any idea how i can achieve this?
To further clarify, here is an image of the screen. Clicking anywhere should call the gesture function, but image should call the cellDelegate.
You can call this method provided by Messagekit it self.
extension ViewController: MessageCellDelegate {
func didTapAvatar(in cell: MessageCollectionViewCell) {
print("Avatar tapped")
}
func didTapMessage(in cell: MessageCollectionViewCell) {
// handle message here
print("Meesage Tapped")
}
In the ChatViewController in viewDidLoad before the super.viewDidLodad
call. You can add:
override func viewDidLoad() {
let tapGesture = UITapGestureRecognizer(target: self, action:
#selector(cellTapped(sender:)))
tapGesture.cancelsTouchesInView = false
messagesCollectionView.addGestureRecognizer(tapGesture)
super.viewDidLoad()
}
#objc
private func cellTapped(sender: UITapGestureRecognizer) {
// Do Something
}
Or you can use the already provided function in the MessageCellDelegate
func didTapImage(in cell: MessageCollectionViewCell) {}

Programmatically Adding UITapGestureRecognizer To UIViews in Outlet Collection

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.

UIImageview click not working

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

Swift 3 UITapGestureRecognizer not receiving tap

I want to add a gesture recognizer to one of my views to detect taps,
here is my code:
class DateTimeContainer: UIView, UIGestureRecognizerDelegate {
override func awakeFromNib() {
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.onTap))
gesture.delegate = self
self.addGestureRecognizer(gesture)
}
func onTap(_ gestureRecognizer: UITapGestureRecognizer) {
openDatePicker()
}
func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool {
if touch.view?.tag != self.datePickerTag && !self.isDatePickerOpen() {
return true
}
return false
}
}
When I tap on my view the code enters into the gestureRecognizer shouldReceive method and enters the condition for which it returns true.
But the onTap method is never called, can someone tell me why?
EDIT
Adding self.isUserInteractionEnabled = true I managed to get it working.
But it had a strange behaviour: it was like it received the tap only in the main view and not in subviews.
So to make it simple I solved by adding a button inside my view and by using:
self.button?.addTarget(self, action: #selector(onTap), for: .touchUpInside)
You may have forgotten to do this:
self.isUserInteractionEnabled = true
Also, typically the UIViewController subclass is usually the target and contains the method used for the tap gesture.
You don't need to set a delegate for a tap gesture (usually)
You can You Gesture
let recognizer = UITapGestureRecognizer(target: self,action:#selector(self.handleTap(recognizer:)))
userImage.isUserInteractionEnabled = true
recognizer.delegate = self as? UIGestureRecognizerDelegate
userImage.addGestureRecognizer(recognizer)
And method call selector
func handleTap(recognizer:UITapGestureRecognizer) {
// do your coding here on method
}
Try Writing the codes
let gesture = UITapGestureRecognizer(target: self, action: #selector(self.onTap))
gesture.delegate = self
self.addGestureRecognizer(gesture)
inside init block not in awakeFromNib()
I noticed that you are adding your gesture on a UIView. As such, at that ViewController where you have added this ContainerView, inside the viewDidLoad method, add this line of code.
override func viewDidLoad() {
super.viewDidLoad()
self.YourContainerView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(YourCurrentViewController.openDatePicker())))
self.YourContainerView.isUserInteractionEnabled = true
}
Note. Do not forget to add isUserInteractionEnabled to true.

Resources