How to cancel LongPressGestureRecognizer?





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















I have a view that has a LongPressGestureRecognizer assigned to it which calls the following method:



@IBAction func longPressOnView1Recognized(_ sender: UIGestureRecognizer) {

if sender.state == .began {
// this runs when user's finger is down a "long time"
}
if sender.state == .ended {
// this runs when user's finger goes up again after the .began state
}

}


This all works as expected, but I'm trying to find a (good/proper) way of being able to programmatically cancel the long press recognizer (in certain circumstances) while the user's finger is still down.



That is, while a user's finger is still down on the view, and the recognizer has entered the .began state, (but before the user has lifted their finger -- before recognizer enters the .ended state)... is there some code we can run that will prevent the method above from firing when the user lifts their finger... like prematurely telling IOS to no longer listen for UP events for the remainder of this gesture?



I've read these docs, but I don't have that much experience with IOS touch, and I can't seem to find any method that is designed for this purpose.



my GestureRecognizer.reset() does not seem to do what I'm describing.



I can think of two possibilities:



1) A boolean flag, that would go inside the if sender.state == .ended {} closure



2) this:



myLongPressRecognizer.isEnabled = false
myLongPressRecognizer.isEnabled = true


Both of these work but seem not so great.










share|improve this question

























  • see this : stackoverflow.com/questions/28414690/…

    – Anbu.Karthik
    Jan 3 at 11:29











  • Disabling a gesture recognizer is the correct way of canceling any events assigned to it. You usually want to enable it right after so those two lines under 2) are completely valid and correct.

    – Matic Oblak
    Jan 3 at 11:55


















1















I have a view that has a LongPressGestureRecognizer assigned to it which calls the following method:



@IBAction func longPressOnView1Recognized(_ sender: UIGestureRecognizer) {

if sender.state == .began {
// this runs when user's finger is down a "long time"
}
if sender.state == .ended {
// this runs when user's finger goes up again after the .began state
}

}


This all works as expected, but I'm trying to find a (good/proper) way of being able to programmatically cancel the long press recognizer (in certain circumstances) while the user's finger is still down.



That is, while a user's finger is still down on the view, and the recognizer has entered the .began state, (but before the user has lifted their finger -- before recognizer enters the .ended state)... is there some code we can run that will prevent the method above from firing when the user lifts their finger... like prematurely telling IOS to no longer listen for UP events for the remainder of this gesture?



I've read these docs, but I don't have that much experience with IOS touch, and I can't seem to find any method that is designed for this purpose.



my GestureRecognizer.reset() does not seem to do what I'm describing.



I can think of two possibilities:



1) A boolean flag, that would go inside the if sender.state == .ended {} closure



2) this:



myLongPressRecognizer.isEnabled = false
myLongPressRecognizer.isEnabled = true


Both of these work but seem not so great.










share|improve this question

























  • see this : stackoverflow.com/questions/28414690/…

    – Anbu.Karthik
    Jan 3 at 11:29











  • Disabling a gesture recognizer is the correct way of canceling any events assigned to it. You usually want to enable it right after so those two lines under 2) are completely valid and correct.

    – Matic Oblak
    Jan 3 at 11:55














1












1








1








I have a view that has a LongPressGestureRecognizer assigned to it which calls the following method:



@IBAction func longPressOnView1Recognized(_ sender: UIGestureRecognizer) {

if sender.state == .began {
// this runs when user's finger is down a "long time"
}
if sender.state == .ended {
// this runs when user's finger goes up again after the .began state
}

}


This all works as expected, but I'm trying to find a (good/proper) way of being able to programmatically cancel the long press recognizer (in certain circumstances) while the user's finger is still down.



That is, while a user's finger is still down on the view, and the recognizer has entered the .began state, (but before the user has lifted their finger -- before recognizer enters the .ended state)... is there some code we can run that will prevent the method above from firing when the user lifts their finger... like prematurely telling IOS to no longer listen for UP events for the remainder of this gesture?



I've read these docs, but I don't have that much experience with IOS touch, and I can't seem to find any method that is designed for this purpose.



my GestureRecognizer.reset() does not seem to do what I'm describing.



I can think of two possibilities:



1) A boolean flag, that would go inside the if sender.state == .ended {} closure



2) this:



myLongPressRecognizer.isEnabled = false
myLongPressRecognizer.isEnabled = true


Both of these work but seem not so great.










share|improve this question
















I have a view that has a LongPressGestureRecognizer assigned to it which calls the following method:



@IBAction func longPressOnView1Recognized(_ sender: UIGestureRecognizer) {

if sender.state == .began {
// this runs when user's finger is down a "long time"
}
if sender.state == .ended {
// this runs when user's finger goes up again after the .began state
}

}


This all works as expected, but I'm trying to find a (good/proper) way of being able to programmatically cancel the long press recognizer (in certain circumstances) while the user's finger is still down.



That is, while a user's finger is still down on the view, and the recognizer has entered the .began state, (but before the user has lifted their finger -- before recognizer enters the .ended state)... is there some code we can run that will prevent the method above from firing when the user lifts their finger... like prematurely telling IOS to no longer listen for UP events for the remainder of this gesture?



I've read these docs, but I don't have that much experience with IOS touch, and I can't seem to find any method that is designed for this purpose.



my GestureRecognizer.reset() does not seem to do what I'm describing.



I can think of two possibilities:



1) A boolean flag, that would go inside the if sender.state == .ended {} closure



2) this:



myLongPressRecognizer.isEnabled = false
myLongPressRecognizer.isEnabled = true


Both of these work but seem not so great.







ios swift uigesturerecognizer






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 3 at 12:48









wvteijlingen

8,92912545




8,92912545










asked Jan 3 at 11:28









Boober BunzBoober Bunz

1,3621036




1,3621036













  • see this : stackoverflow.com/questions/28414690/…

    – Anbu.Karthik
    Jan 3 at 11:29











  • Disabling a gesture recognizer is the correct way of canceling any events assigned to it. You usually want to enable it right after so those two lines under 2) are completely valid and correct.

    – Matic Oblak
    Jan 3 at 11:55



















  • see this : stackoverflow.com/questions/28414690/…

    – Anbu.Karthik
    Jan 3 at 11:29











  • Disabling a gesture recognizer is the correct way of canceling any events assigned to it. You usually want to enable it right after so those two lines under 2) are completely valid and correct.

    – Matic Oblak
    Jan 3 at 11:55

















see this : stackoverflow.com/questions/28414690/…

– Anbu.Karthik
Jan 3 at 11:29





see this : stackoverflow.com/questions/28414690/…

– Anbu.Karthik
Jan 3 at 11:29













Disabling a gesture recognizer is the correct way of canceling any events assigned to it. You usually want to enable it right after so those two lines under 2) are completely valid and correct.

– Matic Oblak
Jan 3 at 11:55





Disabling a gesture recognizer is the correct way of canceling any events assigned to it. You usually want to enable it right after so those two lines under 2) are completely valid and correct.

– Matic Oblak
Jan 3 at 11:55












3 Answers
3






active

oldest

votes


















2














You are all good with disabling and reenabling the gesture recognizer so doing



myLongPressRecognizer.isEnabled = false
myLongPressRecognizer.isEnabled = true


is completely correct.



What I am worried about is you don't completely understand gesture recognizers. You should always use switch statement when handling gesture recognizer. Check the comments:



func handleLongPressGestureRecognizer(_ sender: UIGestureRecognizer) {

switch sender.state {
case .began:
// This will be called only once when the gesture starts
print("Long press did begin at (sender.location(in: sender.view))")
case .changed:
// This will be called whenever your finger moves (at some frequency obviously).
// At this point your long press gesture is acting exactly the same as pan gesture
print("Long press changed position to (sender.location(in: sender.view))")
case .ended:
// This is when user lifts his finger assuming the gesture was not canceled
print("Long press ended at (sender.location(in: sender.view))")
case .cancelled:
// This is equally important as .ended case. You gesture may be canceled for many reasons like a system gesture overriding it. Make sure to implement logic here as well.
print("Long press canceled at (sender.location(in: sender.view))")
case .failed, .possible:
// These 2 have been added additionally at some point. Useless as far I am concerned.
break
}

}


So at least you should handle cancelled status. But also note that the changed status will be triggered whenever the gesture is moved.






share|improve this answer































    1














    You have your solution on hand already. Toggling the UILongPressGestureRecognizer isEnabled is the best way to go. Setting the state property isn't possible, because it's a get-only property.



    open var state: UIGestureRecognizer.State { get } // the current state of the gesture recognizer


    isEnabled property is documented as:




    default is YES. disabled gesture recognizers will not receive touches. when changed to NO the gesture recognizer will be cancelled if it's currently recognizing a gesture.







    share|improve this answer































      1














      You can import the gesture recognizer header:



      import UIKit.UIGestureRecognizer


      That will make the state property a readwrite property. Thus, to cancel the gesture, just change its state to .cancelled.



      So, for example, you can cancel the long press gesture recognizer one second after it was recognized with something like:



      weak var timer: Timer?

      @objc func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
      switch gesture.state {
      case .began:
      print("began")
      timer?.invalidate()
      timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in
      gesture.state = .cancelled
      }

      case .ended, .cancelled:
      print(gesture.state == .ended ? "Ended" : "Cancelled")
      timer?.invalidate()

      default:
      break
      }
      }





      share|improve this answer
























        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54021416%2fhow-to-cancel-longpressgesturerecognizer%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        3 Answers
        3






        active

        oldest

        votes








        3 Answers
        3






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        2














        You are all good with disabling and reenabling the gesture recognizer so doing



        myLongPressRecognizer.isEnabled = false
        myLongPressRecognizer.isEnabled = true


        is completely correct.



        What I am worried about is you don't completely understand gesture recognizers. You should always use switch statement when handling gesture recognizer. Check the comments:



        func handleLongPressGestureRecognizer(_ sender: UIGestureRecognizer) {

        switch sender.state {
        case .began:
        // This will be called only once when the gesture starts
        print("Long press did begin at (sender.location(in: sender.view))")
        case .changed:
        // This will be called whenever your finger moves (at some frequency obviously).
        // At this point your long press gesture is acting exactly the same as pan gesture
        print("Long press changed position to (sender.location(in: sender.view))")
        case .ended:
        // This is when user lifts his finger assuming the gesture was not canceled
        print("Long press ended at (sender.location(in: sender.view))")
        case .cancelled:
        // This is equally important as .ended case. You gesture may be canceled for many reasons like a system gesture overriding it. Make sure to implement logic here as well.
        print("Long press canceled at (sender.location(in: sender.view))")
        case .failed, .possible:
        // These 2 have been added additionally at some point. Useless as far I am concerned.
        break
        }

        }


        So at least you should handle cancelled status. But also note that the changed status will be triggered whenever the gesture is moved.






        share|improve this answer




























          2














          You are all good with disabling and reenabling the gesture recognizer so doing



          myLongPressRecognizer.isEnabled = false
          myLongPressRecognizer.isEnabled = true


          is completely correct.



          What I am worried about is you don't completely understand gesture recognizers. You should always use switch statement when handling gesture recognizer. Check the comments:



          func handleLongPressGestureRecognizer(_ sender: UIGestureRecognizer) {

          switch sender.state {
          case .began:
          // This will be called only once when the gesture starts
          print("Long press did begin at (sender.location(in: sender.view))")
          case .changed:
          // This will be called whenever your finger moves (at some frequency obviously).
          // At this point your long press gesture is acting exactly the same as pan gesture
          print("Long press changed position to (sender.location(in: sender.view))")
          case .ended:
          // This is when user lifts his finger assuming the gesture was not canceled
          print("Long press ended at (sender.location(in: sender.view))")
          case .cancelled:
          // This is equally important as .ended case. You gesture may be canceled for many reasons like a system gesture overriding it. Make sure to implement logic here as well.
          print("Long press canceled at (sender.location(in: sender.view))")
          case .failed, .possible:
          // These 2 have been added additionally at some point. Useless as far I am concerned.
          break
          }

          }


          So at least you should handle cancelled status. But also note that the changed status will be triggered whenever the gesture is moved.






          share|improve this answer


























            2












            2








            2







            You are all good with disabling and reenabling the gesture recognizer so doing



            myLongPressRecognizer.isEnabled = false
            myLongPressRecognizer.isEnabled = true


            is completely correct.



            What I am worried about is you don't completely understand gesture recognizers. You should always use switch statement when handling gesture recognizer. Check the comments:



            func handleLongPressGestureRecognizer(_ sender: UIGestureRecognizer) {

            switch sender.state {
            case .began:
            // This will be called only once when the gesture starts
            print("Long press did begin at (sender.location(in: sender.view))")
            case .changed:
            // This will be called whenever your finger moves (at some frequency obviously).
            // At this point your long press gesture is acting exactly the same as pan gesture
            print("Long press changed position to (sender.location(in: sender.view))")
            case .ended:
            // This is when user lifts his finger assuming the gesture was not canceled
            print("Long press ended at (sender.location(in: sender.view))")
            case .cancelled:
            // This is equally important as .ended case. You gesture may be canceled for many reasons like a system gesture overriding it. Make sure to implement logic here as well.
            print("Long press canceled at (sender.location(in: sender.view))")
            case .failed, .possible:
            // These 2 have been added additionally at some point. Useless as far I am concerned.
            break
            }

            }


            So at least you should handle cancelled status. But also note that the changed status will be triggered whenever the gesture is moved.






            share|improve this answer













            You are all good with disabling and reenabling the gesture recognizer so doing



            myLongPressRecognizer.isEnabled = false
            myLongPressRecognizer.isEnabled = true


            is completely correct.



            What I am worried about is you don't completely understand gesture recognizers. You should always use switch statement when handling gesture recognizer. Check the comments:



            func handleLongPressGestureRecognizer(_ sender: UIGestureRecognizer) {

            switch sender.state {
            case .began:
            // This will be called only once when the gesture starts
            print("Long press did begin at (sender.location(in: sender.view))")
            case .changed:
            // This will be called whenever your finger moves (at some frequency obviously).
            // At this point your long press gesture is acting exactly the same as pan gesture
            print("Long press changed position to (sender.location(in: sender.view))")
            case .ended:
            // This is when user lifts his finger assuming the gesture was not canceled
            print("Long press ended at (sender.location(in: sender.view))")
            case .cancelled:
            // This is equally important as .ended case. You gesture may be canceled for many reasons like a system gesture overriding it. Make sure to implement logic here as well.
            print("Long press canceled at (sender.location(in: sender.view))")
            case .failed, .possible:
            // These 2 have been added additionally at some point. Useless as far I am concerned.
            break
            }

            }


            So at least you should handle cancelled status. But also note that the changed status will be triggered whenever the gesture is moved.







            share|improve this answer












            share|improve this answer



            share|improve this answer










            answered Jan 3 at 12:07









            Matic OblakMatic Oblak

            11.3k11632




            11.3k11632

























                1














                You have your solution on hand already. Toggling the UILongPressGestureRecognizer isEnabled is the best way to go. Setting the state property isn't possible, because it's a get-only property.



                open var state: UIGestureRecognizer.State { get } // the current state of the gesture recognizer


                isEnabled property is documented as:




                default is YES. disabled gesture recognizers will not receive touches. when changed to NO the gesture recognizer will be cancelled if it's currently recognizing a gesture.







                share|improve this answer




























                  1














                  You have your solution on hand already. Toggling the UILongPressGestureRecognizer isEnabled is the best way to go. Setting the state property isn't possible, because it's a get-only property.



                  open var state: UIGestureRecognizer.State { get } // the current state of the gesture recognizer


                  isEnabled property is documented as:




                  default is YES. disabled gesture recognizers will not receive touches. when changed to NO the gesture recognizer will be cancelled if it's currently recognizing a gesture.







                  share|improve this answer


























                    1












                    1








                    1







                    You have your solution on hand already. Toggling the UILongPressGestureRecognizer isEnabled is the best way to go. Setting the state property isn't possible, because it's a get-only property.



                    open var state: UIGestureRecognizer.State { get } // the current state of the gesture recognizer


                    isEnabled property is documented as:




                    default is YES. disabled gesture recognizers will not receive touches. when changed to NO the gesture recognizer will be cancelled if it's currently recognizing a gesture.







                    share|improve this answer













                    You have your solution on hand already. Toggling the UILongPressGestureRecognizer isEnabled is the best way to go. Setting the state property isn't possible, because it's a get-only property.



                    open var state: UIGestureRecognizer.State { get } // the current state of the gesture recognizer


                    isEnabled property is documented as:




                    default is YES. disabled gesture recognizers will not receive touches. when changed to NO the gesture recognizer will be cancelled if it's currently recognizing a gesture.








                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Jan 3 at 11:57









                    GlennGlenn

                    5,69522045




                    5,69522045























                        1














                        You can import the gesture recognizer header:



                        import UIKit.UIGestureRecognizer


                        That will make the state property a readwrite property. Thus, to cancel the gesture, just change its state to .cancelled.



                        So, for example, you can cancel the long press gesture recognizer one second after it was recognized with something like:



                        weak var timer: Timer?

                        @objc func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
                        switch gesture.state {
                        case .began:
                        print("began")
                        timer?.invalidate()
                        timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in
                        gesture.state = .cancelled
                        }

                        case .ended, .cancelled:
                        print(gesture.state == .ended ? "Ended" : "Cancelled")
                        timer?.invalidate()

                        default:
                        break
                        }
                        }





                        share|improve this answer




























                          1














                          You can import the gesture recognizer header:



                          import UIKit.UIGestureRecognizer


                          That will make the state property a readwrite property. Thus, to cancel the gesture, just change its state to .cancelled.



                          So, for example, you can cancel the long press gesture recognizer one second after it was recognized with something like:



                          weak var timer: Timer?

                          @objc func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
                          switch gesture.state {
                          case .began:
                          print("began")
                          timer?.invalidate()
                          timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in
                          gesture.state = .cancelled
                          }

                          case .ended, .cancelled:
                          print(gesture.state == .ended ? "Ended" : "Cancelled")
                          timer?.invalidate()

                          default:
                          break
                          }
                          }





                          share|improve this answer


























                            1












                            1








                            1







                            You can import the gesture recognizer header:



                            import UIKit.UIGestureRecognizer


                            That will make the state property a readwrite property. Thus, to cancel the gesture, just change its state to .cancelled.



                            So, for example, you can cancel the long press gesture recognizer one second after it was recognized with something like:



                            weak var timer: Timer?

                            @objc func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
                            switch gesture.state {
                            case .began:
                            print("began")
                            timer?.invalidate()
                            timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in
                            gesture.state = .cancelled
                            }

                            case .ended, .cancelled:
                            print(gesture.state == .ended ? "Ended" : "Cancelled")
                            timer?.invalidate()

                            default:
                            break
                            }
                            }





                            share|improve this answer













                            You can import the gesture recognizer header:



                            import UIKit.UIGestureRecognizer


                            That will make the state property a readwrite property. Thus, to cancel the gesture, just change its state to .cancelled.



                            So, for example, you can cancel the long press gesture recognizer one second after it was recognized with something like:



                            weak var timer: Timer?

                            @objc func handleLongPress(_ gesture: UILongPressGestureRecognizer) {
                            switch gesture.state {
                            case .began:
                            print("began")
                            timer?.invalidate()
                            timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: false) { _ in
                            gesture.state = .cancelled
                            }

                            case .ended, .cancelled:
                            print(gesture.state == .ended ? "Ended" : "Cancelled")
                            timer?.invalidate()

                            default:
                            break
                            }
                            }






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Apr 6 at 4:01









                            RobRob

                            307k51579749




                            307k51579749






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54021416%2fhow-to-cancel-longpressgesturerecognizer%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                MongoDB - Not Authorized To Execute Command

                                in spring boot 2.1 many test slices are not allowed anymore due to multiple @BootstrapWith

                                How to fix TextFormField cause rebuild widget in Flutter