Add parameter on UITapGestureRecognizer - ios

I would like to ask on how to add a parameter on the UITapGestureRecognizer on my UILabel. So far this is what I got:
self.feedSource.text = source_link
self.feedSource.userInteractionEnabled = true
let feedSourceTapGesture = UITapGestureRecognizer(target: self, action: Selector("openLinkFromFeedSource"))
self.feedSource.addGestureRecognizer(feedSourceTapGesture)
func openLinkFromFeedSource() {
print("tapped")
}
What I want to achieve is when I tapped the label, from openLinkFromFeedSource I can get the value of the self.feedSource.text
Thanks!

You should get this from tap gesture action like this:
func didTapOnView(tap: UITapGestureRecognizer) {
let label = tap.view
// do with that label
}

try this
self.feedSource.userInteractionEnabled = true
let feedSourceTapGesture = UITapGestureRecognizer(target: self, action: Selector("openLinkFromFeedSource:"))
self.feedSource.addGestureRecognizer(feedSourceTapGesture)
func openLinkFromFeedSource(sender: UITapGestureRecognizer) {
let label = sender.view
print("tapped")
}

Related

Is there any property need to set-up to allow the double-tap (Swift)

I can not detect the double-tap in screen? Do i need to turn on the property in the project?
So i try this, but it doesn't work:
let tapRec = UITapGestureRecognizer()
tapRec.addTarget(self, action: #selector(GameScene.doubleTap))
tapRec.numberOfTapsRequired = 2
self.view!.addGestureRecognizer(tapRec)
#objc func doubleTap(){
print ("tap")
}
Try this:
let tapRec = UITapGestureRecognizer(target: self, action: #selector(handleDoubleTap(_:)))
tapRec.delegate = self
tapRec.numberOfTapsRequired = 2
view.userInteractionEnabled = true
view.addGestureRecognizer(tapRec)
And then your function:
extension YourViewController: UIGestureRecognizerDelegate {
func handleDoubleTap(_ gesture: UITapGestureRecognizer){
print("doubletapped")
}
}
Hope this helps!

Getting Tag from Tap Gesture Recognizer

I've got an array of UIImageViews and have programmatically assigned tap gesture recognizers to them.
myImages.forEach{ UIImageView in
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(gesture:)))
tap.numberOfTapsRequired = 1
tap.delegate = self
view.addGestureRecognizer(tap)
}
What's the best way to assign a sender to each (or determine which image was tapped another way)? I've unsuccessfully tried
var tag = sender.view!.tag
Thanks!
in here you need to follow two steps,
step 1
assign the tags for imageview before append to your myImages array.
step 2
get the tag from imageview array and assign to your each gesture
myImages.forEach{
let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(_:)))
tap.numberOfTapsRequired = 1
tap.view?.tag = $0.tag
$0.isUserInteractionEnabled = true
$0.addGestureRecognizer(tap)
}
and handle the func like
#objc func handleTap(_ sender: UITapGestureRecognizer) {
guard let getTag = sender.view?.tag else { return }
print("getTag == \(getTag)")
}
You can use the block provided by UITapGestureRecognizer init to access your images in place.
myImages.forEach { image in
let tap = UITapGestureRecognizer(block: {[weak self] _ in
//Do your stuff here
//print("Image Tapped:", image.debugDescription)
}, delegate: self)
tap.numberOfTapsRequired = 1
image.addGestureRecognizer(tap)
}
If you want to set UITapGestureRecognizer in UICollectionView or UITableView cell then below solution is useful for us.
Step 1 Assign the UITapGestureRecognizer to particuller textview or other view in UICollectionView or UITableView cell.
cell.textView?.delegate = self
cell.textView?.isEditable = false
cell.textView?.isSelectable = true
let tap = UITapGestureRecognizer(target: self, action:#selector(self.onclickLink(_:)))
cell.textView?.tag = indexPath.row
tap.numberOfTapsRequired = 1
cell.textView?.addGestureRecognizer(tap)
Step 2 Get the tag from UITextView or other View in onclick action.
#IBAction func onclickLink(_ sender: UITapGestureRecognizer) {
print("indexPathRow == \(sender.view?.tag ?? 0)")
}

How can we add a UIGestureRecognizer to Outlet Collection?

I'm trying to add a tap gesture to an outlet collection of labels [UILabel], like this:
#IBOutlet var subLabels: [UILabel]!
override func viewDidLoad() {
super.viewDidLoad()
let tap = UITapGestureRecognizer(target: self, action: #selector(HomePageViewController.selectSubLabel(tap:)))
tap.numberOfTapsRequired = 1
tap.cancelsTouchesInView = false
for i in (0..<(subLabels.count)) {
subLabels[i].addGestureRecognizer(tap)
}
}
func selectSubLabel(tap: UITapGestureRecognizer) {
print("Gesture Is WORKING!")
}
and i tried to add it on a single label in storyboard; but NONE are working.
Firstly, you need to allow user interaction on a label (it is turned off by default):
for i in (0..<(subLabels.count)) {
subLabels[i].isUserInteractionEnabled = true
subLabels[i].addGestureRecognizer(tap)
}
but gesture recognizer can observe for gestures only in one view.
So, there are two options:
I. Dedicated gesture recognizer for every label
for i in (0..<(labels.count)) {
let tap = UITapGestureRecognizer(target: self, action: #selector(selectSubLabel(tap:)))
labels[i].isUserInteractionEnabled = true
labels[i].addGestureRecognizer(tap)
}
II. One gesture recognizer for the parent view of the labels
override func viewDidLoad() {
super.viewDidLoad()
for i in (0..<(labels.count)) {
subLabels[i].isUserInteractionEnabled = true
}
let tap = UITapGestureRecognizer(target: self, action: #selector(selectSubLabel(tap:)))
view.addGestureRecognizer(tap)
}
func selectSubLabel(tap: UITapGestureRecognizer) {
let touchPoint = tap.location(in: view)
guard let label = subLabels.first(where: { $0.frame.contains(touchPoint) }) else { return }
// Do your stuff with the label
}
Please check the User Interaction Enabled Attribute of your UIlabel's in Attribute inspector of Xcode. User Interaction Enabled must be ticked for detecting the tap. Please see the picture below,

Pass extra argument for UItapgestureRecognizer with selector

I have two labels, Label1 and Label2. I want to make a single function that prints out which label is tapped by creating UITTapRecognizer for both labels calling the same function with selector that passes an argument. Below is the long way of doing it which is messy but works. If I know how to pass an argument (Int) into the selector, it would be alot cleaner.
let topCommentLbl1Tap = UITapGestureRecognizer(target: self, action: #selector(DiscoverCell().doubleTapTopComment1))
topCommentLbl1Tap.numberOfTapsRequired = 2
topCommentLbl1.userInteractionEnabled = true
topCommentLbl1.addGestureRecognizer(topCommentLbl1Tap)
let topCommentLbl2Tap = UITapGestureRecognizer(target: self, action: #selector(DiscoverCell().doubleTapTopComment2))
topCommentLbl2Tap.numberOfTapsRequired = 2
topCommentLbl2.userInteractionEnabled = true
topCommentLbl2.addGestureRecognizer(topCommentLbl2Tap)
func doubleTapTopComment1() {
print("Double Tapped Top Comment 1")
}
func doubleTapTopComment2() {
print("Double Tapped Top Comment 2")
}
Is there a way to modify the selector method such that I can do something like
func doubleTapTopComment(label:Int) {
if label == 1 {
print("label \(label) double tapped")
}
Short answer: no
The selector is called by the UITapGestureRecognizer, and you have no influence on what parameters it passes.
However, what you can do is query the recognizer's view property to get the same information.
func doubleTapComment(recognizer: UIGestureRecognizer) {
if recognizer.view == label1 {
...
}
else if recognizer.view == label2 {
...
}
}
Provide both gesture recognizers with the same selector that takes a single parameter. That action method will be passed instance of a UIGestureRecognizer, and happily, that gesture recognizer has a property called view, which is the view to which the gr is attached.
... action: #selector(doubleTapTopComment(_:))
func doubleTapTopComment(gestureRecognizer: gr) {
// gr.view is the label, so you can say gr.view.text, for example
}
I believe a UITapGestureRecognizer can only be used for a single view. That said, you can have 2 different UITapGestureRecognizers call the same selector and then access the UITapGestureRecognizer in the function. See the following code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let label1 = UILabel()
label1.backgroundColor = UIColor.blueColor()
label1.frame = CGRectMake(20, 20, 100, 100)
label1.tag = 1
label1.userInteractionEnabled = true
self.view.addSubview(label1)
let label2 = UILabel()
label2.backgroundColor = UIColor.orangeColor()
label2.frame = CGRectMake(200, 20, 100, 100)
label2.tag = 2
label2.userInteractionEnabled = true
self.view.addSubview(label2)
let labelOneTap = UITapGestureRecognizer(target: self, action: #selector(ViewController.whichLabelWasTapped(_:)))
let labelTwoTap = UITapGestureRecognizer(target: self, action: #selector(ViewController.whichLabelWasTapped(_:)))
label1.addGestureRecognizer(labelOneTap)
label2.addGestureRecognizer(labelTwoTap)
}
Both UITapGestureRecognizers call the same function:
func whichLabelWasTapped(sender : UITapGestureRecognizer) {
//print the tag of the clicked view
print (sender.view!.tag)
}
If you try to add one of the UITapGestureRecognizers to both labels, then only the last one added will actually call the function.
You can do like this,
let topCommentLbl1Tap = UITapGestureRecognizer(target: self, action: #selector(labelTapped(_:)))
let topCommentLbl2Tap = UITapGestureRecognizer(target: self, action: #selector(labelTapped(_:)))
label1.addGestureRecognizer(topCommentLbl1Tap)
label2.addGestureRecognizer(topCommentLbl2Tap)
#objc
func textViewTapped(_ sender: UITapGestureRecognizer) {
if(sender.view.tag == label1.tag) {
print("I am label1")
} else if(sender.view.tag == label2.tag) {
print("I am label2")
}
}
don't forgot to set tags to labels.

Swift, UILongPressGestureRecognizer Not working in UIlabel

I am trying long press Gesture in Swift for Copy Option.
But it is not working. It is not identifying the Gesture in UiView Or UILabel either.
Below is my Code
In View DidLoad
let copyLongPress = UILongPressGestureRecognizer(target: self, action: #selector(ContactDetailController.handleLongPress(_:)))
copyLongPress.numberOfTouchesRequired = 0
copyLongPress.delegate = self
copyLongPress.minimumPressDuration=0.5
self.lblDynaMobile.addGestureRecognizer(copyLongPress)
self.lblDynaMobile.userInteractionEnabled = true
self.lblDynaDDI.addGestureRecognizer(copyLongPress)
self.lblDynaDDI.userInteractionEnabled = true
self.GeneralView.addGestureRecognizer(copyLongPress)
self.EmailView.addGestureRecognizer(copyLongPress)
self.AddressView.addGestureRecognizer(copyLongPress)
New Mothod
func handleLongPress(longPressView :UILongPressGestureRecognizer) {
let lblFont:UILabel = (longPressView.view as? UILabel)!
UIPasteboard.generalPasteboard().string = lblFont.text
}
I have added UIGestureRecognizerDelegate too in the Declaration of class
Try this, and see (it's working.)
// in viewDidLoad()
let copyLongPress = UILongPressGestureRecognizer(target: self, action: #selector(self.handleLongPress(_:)))
self.lblDynaMobile.addGestureRecognizer(copyLongPress)
func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
if let lblFont = gesture.view as? UILabel {
//UIPasteboard.generalPasteboard().string = lblFont.text
}
}

Resources