Call number when double tap on label

Hi,


I am trying to call on number located on a label.


When i double tap on it, it should call the number


I have 3 label with 3 different number

I can get the one i touch by

view.addGestureRecognizer(longPressGesture) but the objc function doesnt want argument so i cant pass my call with the one i touch.


in both my function, i force label 2 (lbl2) for testing but i would like to have the one i double tap?


How can i do that?


Thanks


This is my code:



@IBOutlet weak var lbl2: UILabel!
@IBOutlet weak var lbl3: UILabel!
@IBOutlet weak var lbl4: UILabel!

@IBOutlet weak var pvemergency: UIPickerView!  
override func viewDidLoad() { super.viewDidLoad()
// Do any additional setup after loading the view.
pvemergency.dataSource = self
pvemergency.delegate = self
lbl2.isUserInteractionEnabled = true
lbl3.isUserInteractionEnabled = true
lbl4.isUserInteractionEnabled = true
let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.longPress))
view.addGestureRecognizer(longPressGesture)

longPressGesture.minimumPressDuration = 2.0
let doubleTapGesture = UITapGestureRecognizer(target: self, action: #selector(self.doubleTap))
lbl2.addGestureRecognizer(doubleTapGesture)

doubleTapGesture.numberOfTapsRequired = 2
}
@objc func longPress()
{
UIPasteboard.general.string = lbl2.text
}
@objc func doubleTap ()
{

let phone = String(lbl2.text?)
callNumber(phonenumber: phone)
}
func callNumber (phonenumber:String)
{
if let phoneCallURL = URL(string: "tel://\(phonenumber)")
{
let application:UIApplication = UIApplication.shared
if (application.canOpenURL(phoneCallURL))
{
application.open(phoneCallURL,options: [:], completionHandler: nil)
}
}

Replies

When you show some parts of your class, please include the class header.

And use the code insertion feature of this site shown as `< >`.


When a `UIGestureRecognizer` detected its gesture and invokes its action method, iOS passes the gesture recognizer itself as an argument.

So, you can use its `view` property as the source view of the gesture, in your double tap case, it is `UILabel`.

    @objc func doubleTap(_ gestureRecognizer: UIGestureRecognizer) {
        let theLabel = gestureRecognizer.view as! UILabel
        let phone = theLabel.text ?? ""
        callNumber(phonenumber: phone)
    }

Thanks for the reply.


Noted to insert code with <>


if i tried your code i got :


Could not cast value of type 'UIView' (0x1f20f9408) to 'UILabel' (0x1f20f8c10)


I assume this line :


let theLabel = gestureRecognizer.view as! UILabel


detect which label I double tap?


Thanks

I created the gesture in IB. I tested and it works.


What do you get with:


let theLabel = (tapGesture.view as? UILabel)?.text ?? "Nothing"

you mean if i do a print(theLabel) ?


If that, I got "Nothing"

Logic with the problem you have.


Could you add those print:


          print("tapGesture", tapGesture)
          print("tapGesture.view", tapGesture.view)


and tell what you get.


Should be somethings like:

tapGesture Optional(<UITapGestureRecognizer: 0x6000033e8b00; state = Possible; view = <UILabel 0x7febb9d222d0>>)

tapGesture.view Optional(<UILabel: 0x7febb9d222d0; frame = (135.5 151; 42 20.5); text = '₹ 4.752.000'; opaque = NO; autoresize = RM+BM; userInteractionEnabled = NO; gestureRecognizers = <NSArray: 0x600000181ce0>; layer = <_UILabelLayer: 0x600002ce1bd0>>)

In your shown code, you have two use cases on `

addGestureRecognizer`.


One is for `view`, which may not be a `UILabel`:

view.addGestureRecognizer(longPressGesture)

Another is for `lbl2`, which definitely is a `UILabel`:

lbl2.addGestureRecognizer(doubleTapGesture)


So, I have shown you only one alternative for `

doubleTapGesture` which may call `doubleTap(_:)`.

If you have some hidden code, which adds `

doubleTapGesture` on non-UILabel, my code would not work.


But I cannot say any more for such hidden codes. If you want to get something sure, please show all relevant codes.

Hi,


Here my entire code


import UIKit

class ThirdViewController: UIViewController, UIPickerViewDelegate, UIPickerViewDataSource {
    
   
    
    let countrylists = [
        "",
        "Dubai",
        "Geneva",
        "Singapore"]
    
    
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return countrylists.count
    }
    
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return countrylists[row]
    }
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        let selection = countrylists[row]
        switch selection {
        case "Dubai":
            lbl2.text = "999"
            lbl3.text = "998"
            lbl4.text = "997"
                    
        case "Geneva":
            lbl2.text = "117"
            lbl3.text = "118"
            lbl4.text = "144"
        

        case "Singapore":
            lbl2.text = "999"
            lbl3.text = "998"
            lbl4.text = "997"
        

        default:
            lbl2.text = selection
        }
    }
    
    
    @IBOutlet weak var lbl2: UILabel!
    @IBOutlet weak var lbl3: UILabel!
    @IBOutlet weak var lbl4: UILabel!
    
    @IBOutlet weak var pvemergency: UIPickerView!
    
    override func viewDidLoad() {
        super.viewDidLoad()

        // Do any additional setup after loading the view.
        pvemergency.dataSource = self
        pvemergency.delegate = self
        
        lbl2.isUserInteractionEnabled = true
        lbl3.isUserInteractionEnabled = true
        lbl4.isUserInteractionEnabled = true
        
        let longPressGesture = UILongPressGestureRecognizer(target: self, action: #selector(self.longPress))
        view.addGestureRecognizer(longPressGesture)
        //lbl3.addGestureRecognizer(longPressGesture)
        //lbl4.addGestureRecognizer(longPressGesture)
        
        longPressGesture.minimumPressDuration = 2.0
        
        let doubleTapGesture =  UITapGestureRecognizer(target: self, action: #selector(self.doubleTap))
        
        
        
        view.addGestureRecognizer(doubleTapGesture)
        //lbl3.addGestureRecognizer(doubleTapGesture)
        //lbl4.addGestureRecognizer(doubleTapGesture)
        
        doubleTapGesture.numberOfTapsRequired = 2
        
        
        
    }
    
    @objc func longPress(){
        //let phone = String(lbl2.text!)
        //callNumber(phonenumber: phone)
        UIPasteboard.general.string = lbl2.text //here i will need to detect which label i press
        createAlert(title: "Infos", message: "Copied")
    }
    
    @objc func doubleTap (){
        lbl2.text = "double tap" //same here, need to detect which label i double tap
        let phone = String(lbl2.text!)
        
        callNumber(phonenumber: phone)
        //UIPasteboard.general.string = lbl2.text
   }
    

    
    func callNumber (phonenumber:String)
    {
        if let phoneCallURL = URL(string: "tel://\(phonenumber)"){
            
            let application:UIApplication = UIApplication.shared
            
            if (application.canOpenURL(phoneCallURL)){
                application.open(phoneCallURL,options: [:], completionHandler: nil)
            }
        }
        
    }
    
    func createAlert(title:String, message:String){
        
        let msgalert = UIAlertController(title: title, message: message, preferredStyle: UIAlertController.Style.alert )
        msgalert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: { (action) in
            msgalert.dismiss(animated: true, completion: nil)
        }))
        self.present(msgalert, animated: true, completion: nil)
        
    }


Thanks

doiubleTap is not on label, but on whole view. Is it your intent ?

Hi,


At the end I used Gesture from story board and I make 2 @IBAction (for each gesture) and it works


and it much easier and less coding.

So, you have changed the core part of your code.


In your original post:

let doubleTapGesture =  UITapGestureRecognizer(target: self, action: #selector(self.doubleTap))
lbl2.addGestureRecognizer(doubleTapGesture)
 
doubleTapGesture.numberOfTapsRequired = 2

You called `

addGestureRecognizer` on `lbl2`.


And in your new code:

       let doubleTapGesture =  UITapGestureRecognizer(target: self, action: #selector(self.doubleTap))  



        view.addGestureRecognizer(doubleTapGesture)  
        //lbl3.addGestureRecognizer(doubleTapGesture)  
        //lbl4.addGestureRecognizer(doubleTapGesture)  

        doubleTapGesture.numberOfTapsRequired = 2 

You call `addGestureRecognizer` on `view`, those two are completely different codes.


If you change such an important part silently, no one can help you.