Creating a Custom Gesture Recognize

APPLE DOCUMENT:
Creating a Custom Gesture Recognizer
To implement a custom gesture recognizer, first create a subclass of UIGestureRecognizer
in Xcode. Then, add the following import
directive in your subclass’s header file:

import <UIKit/UIGestureRecognizerSubclass.h>

Next, copy the following method declarations from UIGestureRecognizerSubclass.h
to your header file; these are the methods you override in your subclass:

- (void)reset;

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

These methods have the same exact signature and behavior as the corresponding touch-event handling methods described earlier in An App Receives Touches in the Touch-Handling Methods. In all of the methods you override, you must call the superclass implementation, even if the method has a null implementation.
Notice that the state
property in UIGestureRecognizerSubclass.h
is now readwrite
instead of readonly
, as it is in UIGestureRecognizer.h
. Your subclass changes its state by assigning UIGestureRecognizerState
constants to that property.
Implementing the Touch-Event Handling Methods for a Custom Gesture Recognizer
The heart of the implementation for a custom gesture recognizer are the four methods: touchesBegan:withEvent:
, touchesMoved:withEvent:
, touchesEnded:withEvent:
, and touchesCancelled:withEvent:
. Within these methods, you translate low-level touch events into gesture recognition by setting a gesture recognizer’s state. Listing 1-8 creates a gesture recognizer for a discrete single-touch checkmark gesture. It records the midpoint of the gesture—the point at which the upstroke begins—so that clients can obtain this value.
This example has only a single view, but most apps have many views. In general, you should convert touch locations to the screen’s coordinate system so that you can correctly recognize gestures that span multiple views.
Listing 1-8 Implementation of a checkmark gesture recognizer

#import <UIKit/UIGestureRecognizerSubclass.h>

// Implemented in your custom subclass

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

[super touchesBegan:touches withEvent:event];

if ([touches count] != 1) {

self.state = UIGestureRecognizerStateFailed;

return;

}

}

- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {

[super touchesMoved:touches withEvent:event];

if (self.state == UIGestureRecognizerStateFailed) return;

CGPoint nowPoint = [touches.anyObject locationInView:self.view];

CGPoint prevPoint = [touches.anyObject previousLocationInView:self.view];

// strokeUp is a property

if (!self.strokeUp) {

// On downstroke, both x and y increase in positive direction

if (nowPoint.x >= prevPoint.x && nowPoint.y >= prevPoint.y) {

self.midPoint = nowPoint;

// Upstroke has increasing x value but decreasing y value

} else if (nowPoint.x >= prevPoint.x && nowPoint.y <= prevPoint.y) {

self.strokeUp = YES;

} else {

self.state = UIGestureRecognizerStateFailed;

}

}

}

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

[super touchesEnded:touches withEvent:event];

if ((self.state == UIGestureRecognizerStatePossible) && self.strokeUp) {

self.state = UIGestureRecognizerStateRecognized;

}

}

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {

[super touchesCancelled:touches withEvent:event];

self.midPoint = CGPointZero;

self.strokeUp = NO;

self.state = UIGestureRecognizerStateFailed;

}

State transitions for discrete and continuous gestures are different, as described in Gesture Recognizers Operate in a Finite State Machine. When you create a custom gesture recognizer, you indicate whether it is discrete or continuous by assigning it the relevant states. As an example, the checkmark gesture recognizer in Listing 1-8 never sets the state to Began or Changed, because it’s discrete.
The most important thing you need to do when subclassing a gesture recognizer is to set the gesture recognizer’s state
accurately. iOS needs to know the state of a gesture recognizer in order for gesture recognizers to interact as expected. For example, if you want to permit simultaneous recognition or require a gesture recognizer to fail, iOS needs to understand the current state of your recognizer.
For more about creating custom gesture recognizers, see WWDC 2012: Building Advanced Gesture Recognizers.

Resetting a Gesture Recognizer’s State
If your gesture recognizer transitions to Recognized/Ended, Canceled, or Failed, the UIGestureRecognizer
class calls the reset
method just before the gesture recognizer transitions back to Possible.
Implement the reset
method to reset any internal state so that your recognizer is ready for a new attempt at recognizing a gesture, as in Listing 1-9. After a gesture recognizer returns from this method, it receives no further updates for touches that are in progress.
Listing 1-9 Resetting a gesture recognizer

- (void)reset {

[super reset];

self.midPoint = CGPointZero;

self.strokeUp = NO;

}

对于手势的一点理解:

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • ViewsBecause view objects are the main way your applicati...
    梁光飞阅读 642评论 0 0
  • 原创 2017-05-16 剽悍一只猫内容组 剽悍晨读 20170516晨读语音版 来自剽悍晨读 00:0006:...
    阿拉丁神灯624阅读 280评论 0 0
  • 01栈桥观鸟 未到青岛前,先用百度在网上搜了一下青岛各景点的评价,在前三名中选了两处,排名第一的是栈桥。 想像中的...
    干国祥备课老干阅读 643评论 0 12
  • PRINCE2 是一套基于流程管理的项目管理方法,因为便于剪裁 与扩展性强,而被应用于所有类型的项目。它是英国本土...
    Dan独记忆阅读 413评论 0 0