Swift, UILongPressGestureRecognizer Not working in UIlabel - ios

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

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!

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.

Add parameter on UITapGestureRecognizer

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

Swift 2.0 beta trying to make UITextview be able to be dragged

I got this error message: "-[UITextView labelDragged:]: unrecognized selector sent to instance 0x7a2bf400"
Here is my code:
var upperText:UITextView = UITextView()
var lowerText:UITextView = UITextView()
private func addGestureRecognizers(){
let drag1 = UIPanGestureRecognizer(target: upperText,action: Selector("labelDragged:"))
let drag2 = UIPanGestureRecognizer(target: lowerText, action: Selector("labelDragged:"))
view.addGestureRecognizer(drag1)
view.addGestureRecognizer(drag2)
}
func labelDragged(sender : AnyObject?) {
let gesture:UIPanGestureRecognizer = sender as! UIPanGestureRecognizer
let textView:UITextView = gesture.view as! UITextView
let translation:CGPoint = gesture.translationInView(textView)
textView.center = CGPointMake(textView.center.x, textView.center.y + translation.y)
gesture.setTranslation(CGPointZero, inView: textView)
}
This is my first time posting, please help.
Thanks.
You would have to set the target to self:
target: self
I hope you need to study how to add Gesture Recognizer to any View.
private func addGestureRecognizers(){
let drag1 = UIPanGestureRecognizer(target: self,action: Selector("labelDragged:"))
let drag2 = UIPanGestureRecognizer(target: self, action: Selector("labelDragged:"))
upperText.addGestureRecognizer(drag1)
lowerText.addGestureRecognizer(drag2)
}
Replace your code with mine and it will work fine.

How to get UILabel to respond to tap?

I have discovered that I can create UILabel much faster than UITextField and I plan to use UILabel most of the time for my data display app.
To make a long story short though, I wish to let the user tap on a UILabel and have my callback respond to that. Is that possible?
Thanks.
You can add a UITapGestureRecognizer instance to your UILabel.
For example:
UITapGestureRecognizer *tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(labelTapped)];
tapGestureRecognizer.numberOfTapsRequired = 1;
[myLabel addGestureRecognizer:tapGestureRecognizer];
myLabel.userInteractionEnabled = YES;
If you're using storyboards you can do this entire process in the storyboard with no additional code. Add a label to the storyboard, then add a tap gesture to the label. In the Utilities pane, make sure "User Interaction Enabled" is checked for the label. From the tap gesture (at the bottom of your view controller in the storyboard), ctrl+click and drag to your ViewController.h file and create an Action. Then implement the action in the ViewController.m file.
Swift 3.0
Initialize the gesture for tempLabel
tempLabel?.text = "Label"
let tapAction = UITapGestureRecognizer(target: self, action: #selector(self.actionTapped(_:)))
tempLabel?.isUserInteractionEnabled = true
tempLabel?.addGestureRecognizer(tapAction)
Action receiver
func actionTapped(_ sender: UITapGestureRecognizer) {
// code here
}
Swift 4.0
Initialize the gesture for tempLabel
tempLabel?.text = "Label"
let tapAction = UITapGestureRecognizer(target: self, action:#selector(actionTapped(_:)))
tempLabel?.isUserInteractionEnabled = true
tempLabel?.addGestureRecognizer(tapAction)
Action receiver
func actionTapped(_ sender: UITapGestureRecognizer) {
// code here
}
Swift 2.0:
I am adding a nsmutable string as sampleLabel's text, enabling user interaction, adding a tap gesture and trigger a method.
override func viewDidLoad() {
super.viewDidLoad()
let newsString: NSMutableAttributedString = NSMutableAttributedString(string: "Tap here to read the latest Football News.")
newsString.addAttributes([NSUnderlineStyleAttributeName: NSUnderlineStyle.StyleDouble.rawValue], range: NSMakeRange(4, 4))
sampleLabel.attributedText = newsString.copy() as? NSAttributedString
let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: "tapResponse:")
tapGesture.numberOfTapsRequired = 1
sampleLabel.userInteractionEnabled = true
sampleLabel.addGestureRecognizer(tapGesture)
}
func tapResponse(recognizer: UITapGestureRecognizer) {
print("tap")
}
You could use a UIButton instead and set the text to what you want. The button doesn't have to look like a button if you don't want to
To add Tap gesture on UILable
UITapGestureRecognizer *tapAction = [[UITapGestureRecognizer alloc] initWithTarget:self action:#selector(lblClick:)];
tapAction.delegate =self;
tapAction.numberOfTapsRequired = 1;
//Enable the lable UserIntraction
lblAction.userInteractionEnabled = YES;
[lblAction addGestureRecognizer:tapAction];
and to assess the selector method
- (void)lblClick:(UITapGestureRecognizer *)tapGesture {
}
Note: Add UIGestureRecognizerDelegate in .h file
Swift Version:
var tapGesture : UITapGestureRecognizer = UITapGestureRecognizer()
Then inside viewDidLoad(),add this:
let yourLbl=UILabel(frame: CGRectMake(x,y,width,height)) as UILabel!
yourLbl.text = "SignUp"
tapGesture.numberOfTapsRequired = 1
yourLbl.addGestureRecognizer(tapGesture)
yourLbl.userInteractionEnabled = true
tapGesture.addTarget(self, action: "yourLblTapped:")
This works great in Xcode 12 and Swift 5
let tapAction = UITapGestureRecognizer(target: self,action:#selector(actionTapped(_:)))
userLabel?.isUserInteractionEnabled = true
userLabel?.addGestureRecognizer(tapAction)
And action method like -
#objc func actionTapped(_ sender: UITapGestureRecognizer) {
print("tapped")
}
If you want to use Multi line text in your button then create a UILabel with Multiline text and add as a subview in to your button.
for eg:
yourLabel=[Uilabel alloc]init];
yourLabel.frame=yourButtom.Frame;//(frame size should be equal to your button's frame)
[yourButton addSubView:yourLabel]
Swift 3 from Alvin George
override func viewDidLoad() {
super.viewDidLoad()
let newsString: NSMutableAttributedString = NSMutableAttributedString(string: "Tap here to read the latest Football News.")
newsString.addAttributes([NSUnderlineStyleAttributeName: NSUnderlineStyle.styleDouble.rawValue], range: NSMakeRange(4, 4))
sampleLabel.attributedText = newsString.copy() as? NSAttributedString
let tapGesture: UITapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(ViewController.tapResponse))
tapGesture.numberOfTapsRequired = 1
sampleLabel.isUserInteractionEnabled = true
sampleLabel.addGestureRecognizer(tapGesture)
}
func tapResponse(recognizer: UITapGestureRecognizer) {
print("tap")
}
Swift version looks like this:
func addGestureRecognizerLabel(){
//Create a instance, in this case I used UITapGestureRecognizer,
//in the docs you can see all kinds of gestures
let gestureRecognizer = UITapGestureRecognizer()
//Gesture configuration
gestureRecognizer.numberOfTapsRequired = 1
gestureRecognizer.numberOfTouchesRequired = 1
/*Add the target (You can use UITapGestureRecognizer's init() for this)
This method receives two arguments, a target(in this case is my ViewController)
and the callback, or function that you want to invoke when the user tap it view)*/
gestureRecognizer.addTarget(self, action: "showDatePicker")
//Add this gesture to your view, and "turn on" user interaction
dateLabel.addGestureRecognizer(gestureRecognizer)
dateLabel.userInteractionEnabled = true
}
//How you can see, this function is my "callback"
func showDatePicker(){
//Your code here
print("Hi, was clicked")
}
//To end just invoke to addGestureRecognizerLabel() when
//your viewDidLoad() method is called
override func viewDidLoad() {
super.viewDidLoad()
addGestureRecognizerLabel()
}
I personally prefer the method of writing an extension for UILabel. This is what I use.
import UIKit
extension UILabel {
/**
* A map of actions, mapped as [ instanceIdentifier : action ].
*/
private static var _tapHandlers = [String:(()->Void)]()
/**
* Retrieve the address for this UILabel as a String.
*/
private func getAddressAsString() -> String {
let addr = Unmanaged.passUnretained(self).toOpaque()
return "\(addr)"
}
/**
* Set the on tapped event for the label
*/
func setOnTapped(_ handler: #escaping (()->Void)) {
UILabel._tapHandlers[getAddressAsString()] = handler
let gr = UITapGestureRecognizer(target: self, action: #selector(onTapped))
gr.numberOfTapsRequired = 1
self.addGestureRecognizer(gr)
self.isUserInteractionEnabled = true
}
/**
* Handle the tap event.
*/
#objc private func onTapped() {
UILabel._tapHandlers[self.getAddressAsString()]?()
}
}
You would then use it like this from any UILabel instance:
myLabel.setOnTapped {
// do something
}
This can potentially cause some memory leaks I believe, but I haven't determined how best to resolve them yet.

Resources