“This is the 23rd day of my participation in the Gwen Challenge in November. Check out the details: The Last Gwen Challenge in 2021”

Events in iOS

  • In the process of using APP, a variety of events will occur, which can be divided into three categories
  • Touch events (such as clicking…)
  • Accelerator events (e.g., shake…)
  • Remote control events (e.g. Headphones can control phone volume…)

Responder Object (UIResponder)

When it comes to touch events, you need to understand one concept first: responder objects

  • Not every object in iOS can handle events. Only objects that inherit from UIResponder can receive and handle events, often referred to as “responder objects.” UIApplication, UIViewController, UIView, etc

  • UIResponder internally provides the following methods to handle events

  • Touch events

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
    - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
    - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
    - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
    Copy the code
  • Accelerator event

    - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;
    - (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
    - (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event;
    Copy the code
  • Remote control method

    - (void)remoteControlReceivedWithEvent:(UIEvent *)event;
    Copy the code

UIView touch event handling

  • UIView is a subclass of UIResponder that can override the following four methods to handle different touch events

  • When one or more fingers start touching the view, the system automatically calls the following methods of the View

    - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;
    Copy the code
  • When one or more fingers move on the view, the system automatically calls the following methods of the View

    - (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
    Copy the code
  • When one or more fingers leave the view, the system automatically calls the following view methods

        - (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
    Copy the code
  • Before the touch ends, some system event (such as an incoming phone call) interrupts the touch process, and the following method of view is automatically called

    - (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event;
    Copy the code

UITouch

  • When the user touches the screen with a finger, a UITouch object is created associated with the finger
  • One finger corresponds to one UITouch object
  • What the UITouch does: It holds information about your fingers, such as the location, time, and phase of the touch
  • When the finger moves, the system updates the same UITouch object so that it keeps the finger in the same touch position
  • When the finger leaves the screen, the system destroys the corresponding UITouch object
  • UITouchRelevant properties
    • Window The window in which the touch is generated
    • View The view in which the touch was generated
    • TapCount The number of times you press the screen in a short time, judging by the tapCount of one click, double click, or more clicks
    • Timestamp records the time when the touch event was generated or changed, in seconds
    • Phase Indicates the status of the current touch event
  • UITouchRelevant methods
    • The return value represents the position of the touch on the view, which is the position of the view’s coordinate system (starting with the top left corner of the view (0,0)), and the position of the touch on the window if the view argument is passed nil

      [touch locationInView:view];
      Copy the code
    • This method records the position of the previous point

      [touch previousLocationInView:view];
      Copy the code

Note: If you want to listen for multiple fingers in a view, you need to set the properties

// The view needs to support multiple hands
view.multipleTouchEnabled = YES;

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"%ld",(long)touches.count);  / / 2
}
Copy the code

UIEvent

  • Each time an event is generated, a UIEvent object is generated
  • A UIEvent is called an event object and is used to record the time and type of event
  • UIEventRelevant properties
    • The event type
      • Type Enumeration type (touch event, Accelerator event, remote control event)
      • subtype
    • Timestamp Indicates the time when the event occurred
  • UIEventRelevant methods
    • UIEvent provides a method for getting a touch object (UITouch) on a view

A simple example

Implementation requirements: a button can be dragged on screen tasks

1. Customize a UIImageView

@implementation InputImageView

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {        
        UIImage *image = [UIImage imageNamed:@"inputButton"];
        self.image = image;
        self.userInteractionEnabled = YES;
    }
    return self;
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    UITouch *touch = touches.anyObject;
    // Get the current point
    CGPoint currentPoint = [touch locationInView:self];
    // Get the position of the last point
    CGPoint previousPoint = [touch previousLocationInView:self];
    // Get the X-axis offset
    CGFloat offsetX = currentPoint.x - previousPoint.x;
    CGFloat offsetY = currentPoint.y - previousPoint.y;
    // Change the view position
    self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY);
}
@end
Copy the code

2. Actual call

#import "ViewController.h"
#import "InputImageView.h"

@interface ViewController ()
@property (nonatomic,strong) InputImageView *redView;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    InputImageView *inputImageView = [[InputImageView alloc]initWithFrame:CGRectMake(150.150.56.56)];
    [self.view addSubview:inputImageView];
}
@end
Copy the code