One, responder chain
Any class that takes uiresponder as a superclass is a responder. UIView and Uicontrol are subclasses of Uireponder, so all views and all controls are respondents.
1, the initial corresponding device
The event is first passed to the UIApplication object, which is then passed to the application's Uiwindow,uiwindow to select an initial counterpart to handle the event. The initial responder chooses the following option 1, for the touch event, UIWindow determines the user's touch view, and then hands the event to the gesture recognizer that registers the view or registers a higher gesture recognizer with the view level. As long as there is a recognizer capable of handling events, no further search is possible. If not, the touch view is the initial counterpart, and the event is passed to it.
2, for the user shaking the device generated or from remote control device events, will be passed to the first responder
If the initial responder does not process the time, it passes the event to its parent view (if it exists), or to the view controller (if this view is a view of the view controller). If the view controller does not handle the event, it continues to pass to the parent view controller (if present) along the hierarchy of the responder chain.
If there is no view or controller in the entire view hierarchy that can handle events, the event is passed to the application's window. If the window cannot handle the event, and the application delegate is a Uiresponder subclass, the UIApplication object passes it to the application delegate. Finally, if the application delegate is not a subclass of Uiresponder or does not handle the event, the event will be discarded.
4 Gesture Notification method
#pragma mark-touch Event Methods
//The first time a user touches the screen is invoked
-(void) Touchesbegan: (Nsset<uitouch *> *) touches Withevent: (uievent *) event
{
}
///(void) touchescancelled when certain events (such as caller calls) cause a gesture to be interrupted
: (nsset< Uitouch *> *) touches withevent: (Uievent *) event
{
}
//Called when the user's finger leaves the screen
-(void) touchesended: (Nsset <uitouch *> *) touches withevent: (Uievent *) event
{
}
//Triggers when the user's finger is moved
-(void) touchesmoved: ( Nsset<uitouch *> *) touches withevent: (Uievent *) event
{
}
Second, Detect scan events
1, manual detection
//
// ViewController.m
// Swipes
//
// Created by Jierism on 16/8/4.
// Copyright © 2016 Jierism. All rights reserved.
//
#import "ViewController.h"
/ / Set the detection range
Static CGFloat const kMinimmGestureLength = 25;
Static CGFloat const kMaximmVariance = 5;
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (nonatomic) CGPoint gestureStartPoint;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
self.gestureStartPoint = [touch locationInView:self.view];
}
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
UITouch *touch = [touches anyObject];
CGPoint currentPosition = [touch locationInView:self.view];
/ / Returns the absolute value of a float
CGFloat deltaX = fabsf(self.gestureStartPoint.x - currentPosition.x);
CGFloat deltaY = fabsf(self.gestureStartPoint.y - currentPosition.y);
// After obtaining two increments, determine the distance the user has moved in both directions, and detect whether the user moves far enough in one direction but not enough in the other direction to form a swipe motion.
If (deltaX >= kMinimmGestureLength && deltaY <= kMaximmVariance) {
Self.label.text = @"Horizontal swipe detected";
// Wipe text after 2s
Dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)),
Dispatch_get_main_queue(),
^{
Self.label.text = @"";
});
}else if (deltaY >= kMinimmGestureLength && deltaX <= kMaximmVariance){
Self.label.text = @"Vertical swipe detected";
Dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
Self.label.text = @"";
});
}
}
@end
2, recognizer detection
//
// ViewController.m
// Swipes
//
// Created by Jierism on 16/8/4.
// Copyright © 2016 Jierism. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (nonatomic) CGPoint gestureStartPoint;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
/ / Create two gesture recognizers
// 1, horizontal direction recognizer
UISwipeGestureRecognizer *horizontal = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(reportHorizontalSwipe:)];
Horizontal.direction = UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:horizontal];
// 2, vertical direction recognizer
UISwipeGestureRecognizer *vertical = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(reportVerticalSwipe:)];
Vertical.direction = UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:vertical];
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)reportHorizontalSwipe:(UIGestureRecognizer *)recognizer
{
Self.label.text = @"Horizontal swipe detected";
// Wipe text after 2s
Dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)),
Dispatch_get_main_queue(),
^{
Self.label.text = @"";
});
}
- (void)reportVerticalSwipe:(UIGestureRecognizer *)recognizer
{
Self.label.text = @"Vertical swipe detected";
// Wipe text after 2s
Dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)),
Dispatch_get_main_queue(),
^{
Self.label.text = @"";
});
}
@end
Three, implementing a multiple-point light sweep
//
// ViewController.m
// Swipes
//
// Created by Jierism on 16/8/4.
// Copyright © 2016 Jierism. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UILabel *label;
@property (nonatomic) CGPoint gestureStartPoint;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
For (NSUInteger touchCount = 1; touchCount <= 5; touchCount++) {
/ / Create two gesture recognizers
// 1, horizontal direction recognizer
UISwipeGestureRecognizer *horizontal = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(reportHorizontalSwipe:)];
Horizontal.direction = UISwipeGestureRecognizerDirectionLeft | UISwipeGestureRecognizerDirectionRight;
[self.view addGestureRecognizer:horizontal];
// 2, vertical direction recognizer
UISwipeGestureRecognizer *vertical = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(reportVerticalSwipe:)];
Vertical.direction = UISwipeGestureRecognizerDirectionUp | UISwipeGestureRecognizerDirectionDown;
[self.view addGestureRecognizer:vertical];
}
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (NSString *) descriptionForTouchCount: (NSUInteger) touchCount
{
Switch (touchCount) {
Case 1:
Return @"Single";
Case 2:
Return @"Double";
Case 3:
Return @"Triple";
Case 4:
Return @"Quadruple";
Case 5:
Return @"Quintuple";
Default:
Return @"";
}
}
- (void)reportHorizontalSwipe:(UIGestureRecognizer *)recognizer
{
Self.label.text = [NSString stringWithFormat:@"%@ Horizontal swipe detected",[self descriptionForTouchCount:[recognizer numberOfTouches]];;
// Wipe text after 2s
Dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)),
Dispatch_get_main_queue(),
^{
Self.label.text = @"";
});
}
- (void)reportVerticalSwipe:(UIGestureRecognizer *)recognizer
{
Self.label.text = [NSString stringWithFormat:@"%@ Vertical swipe detected",[self descriptionForTouchCount:[recognizer numberOfTouches]];;
// Wipe text after 2s
Dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)),
Dispatch_get_main_queue(),
^{
Self.label.text = @"";
});
}
@end
Four, detect many times light point
VIEWCONTROLLER.M//Taptaps////Created by jierism on 16/8/4. COPYRIGHT©2016 year jierism.
All rights reserved.
#import "ViewController.h" @interface Viewcontroller () @property (weak, nonatomic) Iboutlet Uilabel;
@property (Weak, nonatomic) Iboutlet Uilabel *doublelabel;
@property (Weak, nonatomic) Iboutlet Uilabel *triplelabel;
@property (Weak, nonatomic) Iboutlet Uilabel *quadruplelabel;
@end @implementation Viewcontroller-(void) viewdidload {[Super viewdidload];
Do no additional setup after loading the view, typically from a nib. Create 4 Click gesture recognizers UITapGestureRecognizer *singletap = [[UITapGestureRecognizer alloc] initwithtarget:self action:@
Selector (SINGLETAP)];
singletap.numberoftapsrequired = 1;
singletap.numberoftouchesrequired = 1;
Attach to view [Self.view Addgesturerecognizer:singletap]; UITapGestureRecognizer *doubletap = [[UITapGestureRecognizer alloc] initwithtarget:self action: @selector (DOUBLETAP)]
; Doubletap.numberoftapsrequired = 2;
doubletap.numberoftouchesrequired = 1;
[Self.view Addgesturerecognizer:doubletap];
When the Doubletap response "failed" to run Singletap [Singletap Requiregesturerecognizertofail:doubletap]; UITapGestureRecognizer *tripletap = [[UITapGestureRecognizer alloc] initwithtarget:self action: @selector (TRIPLETAP)]
;
tripletap.numberoftapsrequired = 3;
tripletap.numberoftouchesrequired = 1;
[Self.view Addgesturerecognizer:tripletap];
[Doubletap Requiregesturerecognizertofail:tripletap]; UITapGestureRecognizer *quadrupletap = [[UITapGestureRecognizer alloc] initwithtarget:self action: @selector (
QUADRUPLETAP)];
quadrupletap.numberoftapsrequired = 4;
quadrupletap.numberoftouchesrequired = 1;
[Self.view Addgesturerecognizer:quadrupletap];
[Tripletap Requiregesturerecognizertofail:quadrupletap];
}-(void) Singletap {self.singleLabel.text = @ "single Tap detected"; Dispatch_after (Dispatch_time (Dispatch_time_now, (int64_t) (2 * nsec_per_sec)), Dispatch_get_main_queue (), ^{
Self.singleLabel.text = @ "";
});
}-(void) Doubletap {self.doubleLabel.text = @ "Double Tap detected";
Dispatch_after (Dispatch_time (Dispatch_time_now, (int64_t) (2 * nsec_per_sec)), Dispatch_get_main_queue (), ^{
Self.doubleLabel.text = @ "";
});
}-(void) Tripletap {self.tripleLabel.text = @ "Triple Tap detected";
Dispatch_after (Dispatch_time (Dispatch_time_now, (int64_t) (2 * nsec_per_sec)), Dispatch_get_main_queue (), ^{
Self.tripleLabel.text = @ "";
});
}-(void) Quadrupletap {self.quadrupleLabel.text = @ "Quadruple Tap detected";
Dispatch_after (Dispatch_time (Dispatch_time_now, (int64_t) (2 * nsec_per_sec)), Dispatch_get_main_queue (), ^{
Self.quadrupleLabel.text = @ "";
});
} @end
V. Testing kneading and rotation
#import <UIKit/UIKit.h>
@interface viewcontroller:uiviewcontroller<uigesturerecognizerdelegate>
@end
//
// ViewController.m
// PinchMe
//
// Created by Jierism on 16/8/4.
// Copyright © 2016 Jierism. All rights reserved.
//
#import "ViewController.h"
@interface ViewController ()
@property (strong,nonatomic) UIImageView *imageView;
@end
@implementation ViewController
// current zoom ratio, previous zoom ratio
CGFloat scale, previousScale;
// current rotation angle, previous rotation angle
CGFloat rotation, previousRotation;
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
previousScale = 1;
UIImage *image = [UIImage imageNamed:@"yosemite-meadows"];
self.imageView = [[UIImageView alloc] initWithImage:image];
// Enable interactive features for images
self.imageView.userInteractionEnabled = YES;
self.imageView.center = self.view.center;
[self.view addSubview:self.imageView];
// Create a pinch gesture recognizer
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(doPinch:)];
pinchGesture.delegate = self;
[self.imageView addGestureRecognizer:pinchGesture];
// Create a rotating gesture recognizer
UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(doRorate:)];
rotationGesture.delegate = self;
[self.imageView addGestureRecognizer:rotationGesture];
}
- (BOOL)gestRecognizer:(UIGestureRecognizer *)gestRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
// Allow pinch gestures and rotate gestures to work simultaneously. Otherwise, the gesture recognizer that starts first will block the other
Return YES;
}
// Transform the image based on the zoom and rotation angles obtained in the gesture recognizer
- (void)transformImageView
{
CGAffineTransform t = CGAffineTransformMakeScale(scale * previousScale, scale * previousScale);
t = CGAffineTransformRotate(t, rotation + previousRotation);
self.imageView.transform = t;
}
- (void)doPinch:(UIPinchGestureRecognizer *)gesture
{
Scale = gesture.scale;
[self transformImageView];
If (gesture.state == UIGestureRecognizerStateEnded) {
previousScale = scale * previousScale;
Scale = 1;
}
}
- (void)doRorate:(UIRotationGestureRecognizer *)gesture
{
Rotation = gesture.rotation;
[self transformImageView];
If (gesture.state == UIGestureRecognizerStateEnded) {
previousRotation = rotation + previousRotation;
Rotation = 0;
}
}
@end
VI. Custom gestures
//
// CheckMarkRecognizer.m
// CheckPlease
//
// Created by Jierism on 16/8/4.
// Copyright © 2016 Jierism. All rights reserved.
//
#import "CheckMarkRecognizer.h"
#import "CGPointUtils.h"
#import <UIKit/UIGestureRecognizerSubclass.h> // An important purpose is to make the state property of the gesture recognizer writable, and the subclass will use this mechanism to assert that the gesture we observed has completed successfully.
/ / Set the detection range
Static CGFloat const kMinimunCheckMarkAngle = 80;
Static CGFloat const kMaximumCheckMarkAngle = 100;
Static CGFloat const kMinimumCheckMarkLength = 10;
@implementation CheckMarkRecognizer{
// The first two instance variables provide the previous line segment
CGPoint lastPreviousPoint;
CGPoint lastCurrentPoint;
// the length of the line segment drawn
CGFloat lineLengthSoFar;
}
// Use lastPreviousPoint and lastCurrentPoint to form the first line segment, form an angle with the second line segment to complete the gesture
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[super touchesBegan:touches withEvent:event];
UITouch *touch = [touches anyObject];
CGPoint point = [touch locationInView:self.view];
lastPreviousPoint = point;
lastCurrentPoint = point;
lineLengthSoFar = 0.0;
}
//
// ViewController.m
// CheckPlease
//
// Created by Jierism on 16/8/4.
// Copyright © 2016年 Jierism. All rights reserved.
//
#import "ViewController.h"
#import "CheckMarkRecognizer.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
CheckMarkRecognizer *check = [[CheckMarkRecognizer alloc] initWithTarget:self action:@selector(doCheck:)];
[self.view addGestureRecognizer:check];
self.imageView.hidden = YES;
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (void)doCheck:(CheckMarkRecognizer *)check
{
self.imageView.hidden = NO;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
self.imageView.hidden = YES;
});
}
@end
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.