Skip to content

Touches

Prepared and tested with Xcode 8.3

In this tutorial we cover the following topics

  • General information
  • The family of touch notification methods
    1. Step 1: create a new project
    2. Step 2: set correct options in Attributes Inspector
    3. Step 3: add components
    4. Step 4: add a code
    5. Step 5: run the application
  • Use UIResponder's subclasses to automatic gesture recognition
    1. Step 1: add one more label
    2. Step 2: add a code, part one
    3. Step 3: add a code, part two
    4. Step 4: run the application


General information

To be sure that we know what we are talking about, let's establish basic terminology.

  • Touch. This term refers to any situation when finger is being placed on the screen, dragging across the screen, or being lifted from the screen. The number of touches involved in a gesture is equal to the number of fingers on the screen at the same time.
  • Tap.A tap happens when we touch the screen with a finger (one or more) and then immediately lift it off the screen without moving it on the screen's surface.
  • Gesture. A gesture is any sequence of events reported to the system from the time we touch the screen with one or more fingers until we lift all of our fingers off the screen. No matter how long it takes, as long as one or more fingers remain against the screen, we are still within a gesture (unless a system event, such as an incoming phone call, interrupts it). A gesture is ,,described'' by a system with a series of events. Events are generated when we interact with the device’s screen. They contain information about the touch or touches that occurred. To understand gesture concept it is worth to note that iOS and its librarys doesn’t expose any class or data structure that represents a gesture. In some sense, a gesture is a concept, idea. It is up to a running application to collect, examine the user input stream and make a decision if one is happening. Happily, there exists a class UIGestureRecognizer and its subclasses which can help us when we watch for common gestures.
  • Responder. Any class that has UIResponder as one of its superclasses is a responder. For example, all views and all controls are responders because both UIView and UIControl is a subclass of UIResponder. If a responder handle a particular event, it will usually consume the event, which stops the event’s progression through the responder chain. If a responder doesn’t handle a particular event, it is usually supposed to passes that event up the responder chain. If a responder only partially handles an event, that responder will take an action and forward that event to the next interested responder in the chain. That is why, the following pattern is very common not only in Objective-C but generaly speaking in all event processing environments


The family of touch notification methods

Whenever the user touches the screen for the first time, the system looks for a responder that has a method called touchesBegan:withEvent:. To catch this moment, the moment which may be a simple tap or begining of a complicated gesture, we have to implement this method in our view or your view controller. Both options are correct and it's up to us to make a correct decision based on our application's architecture. That method might look like

Apart this touchesBegan:withEvent: method, there exists three more methods to detect other screen related events.

  • touchesEnded:withEvent: This method is invoked when any of the user’s fingers is removed from the screen.
  • touchesCancelled:withEvent: This method is invoked when the user is in the middle of a gesture when something happens to interrupt it, like the phone ringing. This is where we can do any cleanup we might need so we can start fresh with a new gesture. When this method is called, touchesEnded:withEvent: will not be called for the current gesture.
  • touchesMoved:withEvent: This method is invoked when the user is moving fingers across the screen. This method is called multiple times during a long drag, and each time it is called, we will get another set of touches and another event.

In all cases the NSSet instance called touches contains one UITouch object for each finger that has just been added or removed from the screen or which has just moved or stopped moving. In other words, it tells us what changed between this call and the last time one of our touch notification methods was called.

The UIEvent instance called event has a property called allTouches which is another set of touches.
This property contains one UITouch object for each finger that is currently pressed against the screen, whether or not that finger is currently moving.

From given description we can infer that to track the activity of any given finger, we need to monitor the UITouch object related with it. Each time a finger touches the screen for the first time, a new UITouch object is allocated to represent that finger and added to the set that is passed in the allTouches property of each UIEvent. All future events that report activity for that same finger will contain the same UITouch instance in both the allTouches set and in the touches argument, until that finger is removed from the screen. Have in mind that in the latter case, it will not be present if there is no activity to report for that finger.

  1. Step 1: create a new project
    Create a new project

    1. Select File | New | Project...
    2. From iOS tab select Single View Application on the template selection sheet.
    3. As the product name enter iOS Touches Basic Application
    4. Set the Language to Objective-C, devices pop-up button to Universal and make sure the check box labeled Use Core Data is unchecked.
  2. Step 2: set correct options in Attributes Inspector
    1. Single-click either the background of the view we are working on or the View icon in the Document Outline, and then bring up the Attributes Inspector.
    2. On the Attributes Inspector, go to the View section and varify if both User Interaction Enabled and Multiple Touch are checked.
  3. Step 3: add components
    1. Place three labels on the screen: one for type of notification method, one for the number of taps and one for the number of touches.
    2. Add all necessary constraints.
    3. Double-click each label and for the first enter text Method, for the second Taps and for the third Touches.
    4. Single-click ViewController.m and add three outlets to the class extension at the top of the file as we did it many times before (use control drag from component (label) to the class source file). As a result we shoud get
  4. Step 4: add a code
    1. Single-click ViewController.m and add the following code to the class’s @implementation section
  5. Step 5: run the application
    In my case I got the following sequence of messages for a single tap and next for a touch and move

    ...single tap...
    2017-05-01 23:30:36.348 iOS Touches Basic Application[1322:81996] touchesBegan
    2017-05-01 23:30:36.350 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:36.351 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:36.355 iOS Touches Basic Application[1322:81996] touchesEnded
    2017-05-01 23:30:36.355 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:36.355 iOS Touches Basic Application[1322:81996] 1 touches detected
    ..touch and move...
    2017-05-01 23:30:41.581 iOS Touches Basic Application[1322:81996] touchesBegan
    2017-05-01 23:30:41.582 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:41.582 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:42.825 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:42.826 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:42.826 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:42.842 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:42.843 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:42.843 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:42.865 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:42.866 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:42.866 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:42.881 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:42.882 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:42.882 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:42.897 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:42.898 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:42.898 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:42.913 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:42.914 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:42.914 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:42.937 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:42.938 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:42.938 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:42.953 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:42.954 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:42.954 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:42.969 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:42.970 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:42.970 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:42.994 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:42.994 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:42.994 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:43.010 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:43.010 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:43.010 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:43.034 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:43.034 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:43.034 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:43.050 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:43.050 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:43.050 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:43.076 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:43.076 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:43.076 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:43.098 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:43.098 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:43.098 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:43.114 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:43.114 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:43.114 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:43.130 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:43.130 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:43.131 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:43.146 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:43.146 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:43.147 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:43.162 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:43.162 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:43.163 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:43.194 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:43.194 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:43.194 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:43.226 iOS Touches Basic Application[1322:81996] touchesMoved
    2017-05-01 23:30:43.226 iOS Touches Basic Application[1322:81996] 1 taps detected
    2017-05-01 23:30:43.227 iOS Touches Basic Application[1322:81996] 1 touches detected
    2017-05-01 23:30:43.651 iOS Touches Basic Application[1322:81996] touchesEnded
    2017-05-01 23:30:43.651 iOS Touches Basic Application[1322:81996] 0 taps detected
    2017-05-01 23:30:43.652 iOS Touches Basic Application[1322:81996] 1 touches detected

    1. Use UIResponder's subclasses to automatic gesture recognition

      We will continue to work with a previous project.

      1. Step 1: add one more label
        1. Place one more label on the screen below the previously added labels - we will use it to show swipe notifications.
        2. Add all necessary constraints.
        3. Double-click newly added label and enter text Swipe
        4. Single-click ViewController.m and add an outlet related to a new label as we did it before.
      2. Step 2: add a code, part one
        1. Single-click ViewController.m and add the following code at the end of the class’s @implementation section
      3. Step 3: add a code, part two
        1. Single-click ViewController.m and update the code of viewDidLoad method
      4. Step 4: run the application