0

I have a screen with 6 buttons. All the buttons are connected to one IBAction. They are tagged and I use a switch statement to determine which one was tapped.

How can I add a Long and Tap gesture to each button? So for example when I tap button 1 it know if its a long gesture or a tap gesture?

So if I tap the button will do something different then when I long press.

Thanks.

@IBAction func playPauseAudioButton(sender: UIButton) {

    switch sender.tag {

    case 1:
        //Tap Gesture 
        //Long Gesture
        //I need this for every button
        print("1")

    case 2:
        print("2")

    case 3:
        print("3")

    case 4:

    case 5:
        print("5")

    case 6:
        print("6")

    default:
        print("Default")
    }
}
Bista
  • 7,869
  • 3
  • 27
  • 55
JohnCarp
  • 49
  • 8

2 Answers2

5

Do it like this

@IBAction func playPauseAudioButton(sender: AnyObject) {
    let tapGesture = UITapGestureRecognizer(target: self, action: "normalTap:")
    let longGesture = UILongPressGestureRecognizer(target: self, action: "longTap:")
    tapGesture.numberOfTapsRequired = 1
    sender.addGestureRecognizer(tapGesture)
    sender.addGestureRecognizer(longGesture)
}

func normalTap(sender : UIGestureRecognizer) {
    let recognizer: UIGestureRecognizer = sender
    let tag: Int = recognizer.view!.tag

    switch tag {
    case 1:
        // Do some action for button 1
        print("1")
    case 2:
        print("2")
    case 3:
        print("3")
    case 4:
        print("4")
    case 5:
        print("5")
    case 6:
        print("6")
    default:
        print("Default")
    }
}

func longTap(sender : UIGestureRecognizer) {
    let recognizer: UIGestureRecognizer = sender
    let tag: Int = recognizer.view!.tag

    if sender.state == .Ended {
        print("UIGestureRecognizerStateEnded")
        //Do Whatever You want on End of Gesture
    }
    else if sender.state == .Began {
        print("UIGestureRecognizerStateBegan.")
        //Do Whatever You want on Began of Gesture
    }

    switch tag {
    case 1:
        // Do some action for button 1
        print("1")
    case 2:
        print("2")
    case 3:
        print("3")
    case 4:
        print("4")
    case 5:
        print("5")
    case 6:
        print("6")
    default:
        print("Default")
    }
}
Rashwan L
  • 38,237
  • 7
  • 103
  • 107
  • Thanks for the help! So far it seem to be working ok but when I press the long gesture the numbers print out twice? Do you know why? – JohnCarp Jan 09 '16 at 07:35
  • It´s because `UILongPressGestureRecognizer` has two states, began and ended. I have update the code so that you can choose which one you want to use @JohnCarp. – Rashwan L Jan 09 '16 at 07:40
  • There seem to be another issue. When I tap the button the first time it doesn't work. When I tap it the second then it works?(tap gesture). For the long press if i keep the button holding down it keeps printing the number. Is there anyway to fix this? thanks so much! – JohnCarp Jan 09 '16 at 08:03
  • @ Rashwan L So I have to connect every single button individually to an outlet and write this code for each one? – JohnCarp Jan 09 '16 at 08:33
  • Also when i keep holding down the button it keep writing out to the console. How do I prevent it from doing this? I just want it to do its action once when i longPress it. Than you! – JohnCarp Jan 09 '16 at 08:37
  • Just add your code within the `sender.state == .Ended`and `sender.state == .Began` if-statements. These only executes ones for each press. If you check the print long you will see that `UIGestureRecognizerStateEnded`and `UIGestureRecognizerStateBegan`is only printed once. – Rashwan L Jan 09 '16 at 08:43
  • If i press and hold the button down it keeps executing my code. In the debugger you see for example the case 1 keeps writing out 1111111 until I let it go. – JohnCarp Jan 09 '16 at 08:48
  • If you want to add an event for tag 1 for example when the user releases the button (.Ended) then you need to add this to your case-statment: `if sender.state == .Ended { print("1") }` instead of just `print("1")`. You need to capture the .Began and .Ended events, that´s why you need to add these checks. – Rashwan L Jan 09 '16 at 08:51
  • Is there anyway I can send you my sample project? By email? – JohnCarp Jan 09 '16 at 09:03
  • You can upload it and send the link to me here. – Rashwan L Jan 09 '16 at 09:04
  • @ Rashwan L just sent you the link. When you run it press and hold one of the buttons and you'll see what the printout looks like. – JohnCarp Jan 09 '16 at 09:39
  • Yes, I understood what your issue were and as I said you need to call the sender state within your case. [Here](https://www.dropbox.com/s/xj1b9v08kidry8s/stackTestTaps.zip?dl=0) is an updated example of your code, I added the sender state to button 1 and button 2 but not button 3 so that you can see the difference. – Rashwan L Jan 09 '16 at 09:45
  • Thanks so much for the help and being patient. Is there anyway I can get in contact with you by email or something in case I get stuck along the way? Im new at thesis you can tell and you been super helpful! – JohnCarp Jan 09 '16 at 09:53
  • Np, glad it worked out for you. I´m around here at SO, if you have a question post it here and either me or someone else will help you :) – Rashwan L Jan 09 '16 at 09:56
  • I get this error when i present the and hold the messenger . I added this code to my main project. Do you know why this happens? 2016-01-09 05:03:14.764 Major Keys[2142:621821] Warning: Attempt to present on which is already presenting (null) 2016-01-09 05:03:16.215 Major Keys[2142:621821] Attempting to load the view of a view controller while it is deallocating is not allowed and may result in undefined behavior () – JohnCarp Jan 09 '16 at 10:08
  • @JohnCarp, consider accepting this answer so that others can make use of it in the future. Regarding your other issue, read [this](http://stackoverflow.com/questions/32704169/attempting-to-load-the-view-of-a-view-controller-while-it-is-deallocating-ui) thread. – Rashwan L Jan 09 '16 at 10:19
  • @ Rashwan L Just accepted it and voted up. It will show when I have more points. Thanks again! – JohnCarp Jan 09 '16 at 10:25
  • Sure what @JohnCarp? – Rashwan L Jan 13 '16 at 22:54
0

Define two IBActions and set one Gesture Recognizer to each of them. This way you can perform two different actions for each gesture.

You can set each Gesture Recognizer to different IBActions in the interface builder.

@IBAction func tapped(sender: UITapGestureRecognizer)
{
println("tapped")
//Your animation code.
}

@IBAction func longPressed(sender: UILongPressGestureRecognizer)
{
println("longpressed")
//Different code
}

Through code without interface builder

let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: "tapped:")
self.view.addGestureRecognizer(tapGestureRecognizer)

let longPressRecognizer = UILongPressGestureRecognizer(target: self, action: "longPressed:")
self.view.addGestureRecognizer(longPressRecognizer)

func tapped(sender: UITapGestureRecognizer)
{
 println("tapped")
}

func longPressed(sender: UILongPressGestureRecognizer)
{
println("longpressed")
}

Hope this helps you.

AddWeb Solution Pvt Ltd
  • 21,025
  • 5
  • 26
  • 57