2

I need to know that a user started to touch the screen and then know when he is not touching it anymore.

With touchesBegan and touchesEnded I can get such information. However, if the user is swiping his fingers, then I know he started doing it with touchesMoved.
However I am not able to check when he is no longer touching the screen. Basically , touchesEnded will not fire after the user stopped swipping. Any ideas?

Example of my code:

override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {


    if let touch = touches.first {
    print("Finger touched!")
    }
    super.touchesBegan(touches, withEvent:event)
}


override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first {

        print("Finger is swipping!")

    }
    super.touchesBegan(touches, withEvent:event)
}

override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) {
    if let touch = touches.first {

        print("finger is not touching.") //this will not fire if finger stopped swipping

    }
    super.touchesBegan(touches, withEvent:event)
}
Duarte
  • 127
  • 4
  • 14
  • You will get either `touchesEnded(_:,withEvent:)` or `touchesCancelled(_:,withEvent:)` for every touch. Are you overriding `touchesCancelled(_:,withEvent:)`? – rob mayoff Oct 23 '15 at 21:14
  • 4
    Why are you calling `super.touchesBegan` on all 3 methods? – joern Oct 23 '15 at 21:21
  • Hi. I am trying to follow your suggestion using 'code' override func touchesCancelled(touches: Set, withEvent event: UIEvent!) { super.touchesCancelled(touches, withEvent: event); } but I get the error: Method does not overide any method from its superclass – Duarte Oct 23 '15 at 21:30
  • It was just a test... – Duarte Oct 23 '15 at 21:31

3 Answers3

3

working in Swift 3

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    if touches.first != nil {
        print("Finger touched!")
    }

}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if touches.first != nil {
        print("finger is not touching.")  
    }
}

override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
    if touches.first != nil {
        print("Touch Move")
    }
}
RosS
  • 317
  • 2
  • 6
  • 24
2

You said:

print("finger is not touching.") //this will not fire if finger stopped swipping

You're right that it will not fire if the finger stopped moving. But it will fire if the finger leaves the screen (stops touching), which is what you asked about ("no longer touching the screen").

matt
  • 515,959
  • 87
  • 875
  • 1,141
1

touchesBegan:withEvent: always gets called for one or more fingers when they touch the screen that are considered part of the same touch event. touchesMoved:withEvent: gets fired when one or more fingers in the event move. touchesEnded:withEvent: get fired when one or more of the fingers in the touch event are removed from the screen. Lastly, touchesCancelled:withEvent: is called if the whole event is invalidated (i.e., cancelled).

For a given event you will always receive one or more calls to touchesBegan:withEvent:, probably many calls to touchesMoved:withEvent, and then either one or more calls to touchesEnded:withEvent: or touchesCancelled:withEvent:

A few things to consider here:

  1. You should always implement all four of these methods, even if you do nothing, to prevent partial events from going up the responder chain (which is what the super implementation does).
  2. You should not call super if you are handling the events.
  3. If you do call super because you want to dispatch the events up the responder chain, you must call the correct super method (you are calling touchesBegan:withEvent: on super in your touchesMoved:withEvent implementation

To answer your question specifically, you implement touchesEnded:withEvent to know when the user has stopped touching the screen with one or more touches that are part of the event.

Charles A.
  • 10,685
  • 1
  • 42
  • 39
  • I am sorry, I am very newbie in this. But in the code example I gave, the message "finger is not touching." will never be shown, in case the user swipped the screen. However it will be shown IF the user pressed down and then up without swipping. – Duarte Oct 23 '15 at 21:43
  • Try removing the calls to super from your implementations. They should not be there. – Charles A. Oct 23 '15 at 22:42
  • Also, have you considered using a `UISwipeGestureRecognizer` or `UIPanGestureRecongizer`? It's rare that you really need to write your own gesture handling code these days. – Charles A. Oct 23 '15 at 22:44
  • Thank you Charles A. That sorted the issue! :) – Duarte Oct 24 '15 at 00:17
  • It's funny, if you want to check if a user is panning a mapView, then the touchesEnded:withEvent won't fire after swiping. Basically, what I need to do, is to prevent a certain function to be executed while a user is dragging a mapView. Until now, I could not find a working solution. – Duarte Oct 24 '15 at 00:24