美文网首页api-UI
手势——UIGestureRecognizer

手势——UIGestureRecognizer

作者: 云天涯丶 | 来源:发表于2018-05-08 14:19 被阅读144次

    一、简介

    UIGestureRecognizer是具体手势识别器的基类。

    手势识别器对象(或简单地说是手势识别器)将用于识别触摸序列(或其他输入)的逻辑进行解耦,并对该识别进行操作。当这些对象中的一个识别到共同的手势时,或者在某些情况下,手势发生变化时,它会向每个指定的目标对象发送一条操作消息。

    UIGestureRecognizer的具体子类如下:
    ①UITapGestureRecognizer——点击
    ②UIPinchGestureRecognizer——捏合
    ③UIRotationGestureRecognizer——旋转
    ④UISwipeGestureRecognizer——轻扫
    ⑤UIPanGestureRecognizer——平移(拖动)
    ⑥UIScreenEdgePanGestureRecognizer——屏幕边缘附近开始的平移(拖动)
    ⑦ UILongPressGestureRecognizer——长按

    UIGestureRecognizer类定义了一组可以为所有具体手势识别器配置的常见行为。它还可以与其委托(采用UIGestureRecognizerDelegate协议的对象)进行通信,从而对某些行为进行更细致的定制。

    手势识别器通过触摸hit-tested特定视图(view)和所有视图的子视图。 因此它必须与视图相关联。 为了建立关联,你必须调用UIView方法addGestureRecognizer :.

    手势识别器不参与视图的响应者链。

    二、api

    1、UIGestureRecognizer
    NS_CLASS_AVAILABLE_IOS(3_2) @interface UIGestureRecognizer : NSObject
    // 初始化并添加target和action
    - (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action NS_DESIGNATED_INITIALIZER; // designated initializer
    
    // 添加target和action,可以多次添加
    - (void)addTarget:(id)target action:(SEL)action;    
    
    /* 移除target和action
    Passing nil for target matches all targets and passing NULL for action matches all actions.
     */
    - (void)removeTarget:(nullable id)target action:(nullable SEL)action;
    // 手势识别器的当前状态
    @property(nonatomic,readonly) UIGestureRecognizerState state;  
    
    @property(nullable,nonatomic,weak) id <UIGestureRecognizerDelegate> delegate;
    
    @property(nonatomic, getter=isEnabled) BOOL enabled; 
    
    // 使用addGestureRecognizer:方法将手势识别器附加(或添加)到UIView对象
    @property(nullable, nonatomic,readonly) UIView *view;           
    
    /* 影响识别手势时是否将触摸传递到视图。 
    当此属性为YES(默认值)并且receiver识别其手势时,将发生的的手势触摸将不会传递到view,并且之前传送的touches会通过touchesCancelled:withEvent:消息发送到view中取消。 如果手势识别器无法识别其手势,或者此属性的值为NO,则该view会接收多点触摸序列中的所有触摸。
    注:手势冲突或者一些好的效果时可以使用这个属性
    */
    @property(nonatomic) BOOL cancelsTouchesInView;     
    
    /* 确定接收器是否延迟将开始阶段的触摸发送到其视图。
    当此属性的值为NO(默认值)时,view将与receiver并行地分析UITouchPhaseBegan和UITouchPhaseMoved中的触摸事件。当属性的值为YES时,window将UITouchPhaseBegan阶段中的touch objects推迟传递到view。如果手势识别器随后识别其手势,则丢弃这些触摸对象。如果手势识别器无法识别其手势,那么window将这些对象通过touchesBegan:withEvent:消息传递给view(并且可能还会跟随touchesMoved:withEvent:消息来通知其触摸的当前位置) 。将此属性设置为YES以防止视图处理可能被识别为此手势的一部分的UITouchPhaseBegan阶段中的任何触摸。
     */
    @property(nonatomic) BOOL delaysTouchesBegan;  
    
    /* 确定接收器是否延迟将结束阶段的触摸发送到其视图。 
    当此属性的值为YES(默认值)且receiver正在分析触摸事件时,window会将UITouchPhaseEnded阶段中的touch objects推迟传递到附加视图。如果手势识别器随后识别其手势,则取消这些触摸对象(通过touchesCancelled:withEvent:消息)。如果手势识别器无法识别其手势,则window在调用view的touchesEnded:withEvent:方法时传递这些对象。将此属性设置为NO,以便在手势识别器正在分析相同的触摸时将UITouchPhaseEnded中的触摸对象传送到view。*/       
    @property(nonatomic) BOOL delaysTouchesEnded;   
    
    @property(nonatomic, copy) NSArray<NSNumber *> *allowedTouchTypes NS_AVAILABLE_IOS(9_0); // Array of UITouchTypes as NSNumbers.
    @property(nonatomic, copy) NSArray<NSNumber *> *allowedPressTypes NS_AVAILABLE_IOS(9_0); // Array of UIPressTypes as NSNumbers.
    
    /* 手势识别器是否同时考虑不同类型的触摸。
    当此属性的值为YES时,手势识别器会自动忽略其类型与初始触摸类型不匹配的新触摸。 如果值为NO,则手势识别器将接收其类型在allowedTouchTypes属性中列出的所有触摸。 */
    @property (nonatomic) BOOL requiresExclusiveTouchType NS_AVAILABLE_IOS(9_2); // defaults to YES
    
    /* 手势依赖
    创建与另一个手势识别器的关系,这将阻止此手势的动作被调用,直到otherGestureRecognizer转换为UIGestureRecognizerStateFailed。
    如果otherGestureRecognizer转换为UIGestureRecognizerStateRecognized或UIGestureRecognizerStateBegan,则此识别器将转换为UIGestureRecognizerStateFailed
     */
    - (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;
    
    
    /* 手势在给定视图中的位置的点。
    传入nil,则代表手势在window的位置*/
    - (CGPoint)locationInView:(nullable UIView*)view; 
    
    // touch数量
    #if UIKIT_DEFINE_AS_PROPERTIES
    @property(nonatomic, readonly) NSUInteger numberOfTouches;  
    #else
    - (NSUInteger)numberOfTouches; 
    #endif
    
    - (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view;
    
    @property (nullable, nonatomic, copy) NSString *name API_AVAILABLE(ios(11.0), tvos(11.0)); // name for debugging to appear in logging
    
    @end
    
    // 代理
    @protocol UIGestureRecognizerDelegate <NSObject>
    @optional
    // 当手势识别器尝试从UIGestureRecognizerStatePossible转换出来时调用。 返回NO会导致它转换到UIGestureRecognizerStateFailed
    - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
    
    /* 当gestureRecognizer或otherGestureRecognizer其中一个的识别被另一个识别时调用
    返回YES以允许两者同时识别。 默认实现返回NO(默认情况下,不能同时识别两个手势)。注意:返回YES保证允许同时识别。 返回NO不能保证防止同时识别,因为另一个手势的代表可能会返回YES 
    Simultaneously:同时地*/
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
    
    /* 是否当前的手势识别器必须等待识别其手势,直到指定的手势识别器失败。
    每次尝试识别时都会调用此方法一次,因此可以动态更改失败要求。 两个手势识别器不必属于相同的视图层次结构。
    返回YES保证设置失败要求; 返回NO不会阻止其他手势识别器设置失败要求。*/
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
    
    /* 是否在允许另一个手势识别器识别其手势之前当前手势识别器失败。 */
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
    
    /*在 touchesBegan:withEvent:调用以获得新的touch
    返回NO以防止手势识别器看到此touch。 */
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;
    
    /*在 pressesBegan:withEvent:调用以获得新的press
    返回NO以防止手势识别器看到此press。 */
    - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceivePress:(UIPress *)press;
    
    @end
    
    

    手势状态:

    typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
        UIGestureRecognizerStatePossible,   // 识别器尚未识别其手势,但可能正在评估触摸事件。这是默认状态
        
        UIGestureRecognizerStateBegan,      // 识别器已经接收到被识别为手势的触摸。该操作方法将在run loop的下一个回合中被调用
        UIGestureRecognizerStateChanged,    // 识别器已经接收到被识别为手势改变的触摸。该操作方法将在run loop的下一个回合中被调用
        UIGestureRecognizerStateEnded,      // 识别器已经接收到被识别为手势结束的触摸。操作方法将在run loop的下一个回合中被调用,并且识别器将被重置为UIGestureRecognizerStatePossible
        UIGestureRecognizerStateCancelled,  // 识别器已经接收到导致手势取消的触摸。该操作方法将在run loop的下一个回合中被调用。识别器将被重置为UIGestureRecognizerStatePossible
        
        UIGestureRecognizerStateFailed,     // 识别器已经接收到不能被识别为手势的触摸序列。操作方法将不会被调用,并且识别器将被重置为UIGestureRecognizerStatePossible
        
        // 离散手势 - 识别离散事件但不报告变化(例如,敲击)的手势识别器不会通过开始和已更改状态转换,并且不会失败或被取消
        UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded
    };
    
    2、UITapGestureRecognizer:点击
    NS_CLASS_AVAILABLE_IOS(3_2) @interface UITapGestureRecognizer : UIGestureRecognizer
    // 点击次数 Default is 1
    @property (nonatomic) NSUInteger  numberOfTapsRequired; 
    // 点按的手指数 Default is 1
    @property (nonatomic) NSUInteger  numberOfTouchesRequired __TVOS_PROHIBITED;  
    
    @end
    
    3、UIPinchGestureRecognizer:捏合
    NS_CLASS_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED @interface UIPinchGestureRecognizer : UIGestureRecognizer
    // 缩放因子
    @property (nonatomic)          CGFloat scale; 
    // 按每秒缩放系数缩放的速度。
    @property (nonatomic,readonly) CGFloat velocity; 
    
    @end
    
    4、UIRotationGestureRecognizer:旋转
    NS_CLASS_AVAILABLE_IOS(3_2) __TVOS_PROHIBITED @interface UIRotationGestureRecognizer : UIGestureRecognizer
    // 旋转值
    @property (nonatomic)          CGFloat rotation; 
    // 旋转手势的速度,以弧度/秒为单位。
    @property (nonatomic,readonly) CGFloat velocity; 
    
    @end
    
    5、UISwipeGestureRecognizer:清扫
    typedef NS_OPTIONS(NSUInteger, UISwipeGestureRecognizerDirection) {
        UISwipeGestureRecognizerDirectionRight = 1 << 0,
        UISwipeGestureRecognizerDirectionLeft  = 1 << 1,
        UISwipeGestureRecognizerDirectionUp    = 1 << 2,
        UISwipeGestureRecognizerDirectionDown  = 1 << 3
    };
    
    NS_CLASS_AVAILABLE_IOS(3_2) @interface UISwipeGestureRecognizer : UIGestureRecognizer 
    // 触摸次数 default is 1
    @property(nonatomic) NSUInteger                        numberOfTouchesRequired __TVOS_PROHIBITED; 
    // 滑动的方向,可以多个方向  默认:UISwipeGestureRecognizerDirectionRight
    @property(nonatomic) UISwipeGestureRecognizerDirection direction;               
    
    @end
    
    6、UIPanGestureRecognizer:平移(拖动)
    NS_CLASS_AVAILABLE_IOS(3_2) @interface UIPanGestureRecognizer : UIGestureRecognizer 
    
    @property (nonatomic)          NSUInteger minimumNumberOfTouches __TVOS_PROHIBITED;   // default is 1. 最小手指数量
    @property (nonatomic)          NSUInteger maximumNumberOfTouches __TVOS_PROHIBITED;   // default is UINT_MAX. 最大手指数量
    
    // 触点为原点,平移后触点相对于原点的坐标位置。
    - (CGPoint)translationInView:(nullable UIView *)view; 
    - (void)setTranslation:(CGPoint)translation inView:(nullable UIView *)view;
    
    // 平移手势在指定view的坐标系中的速度。
    - (CGPoint)velocityInView:(nullable UIView *)view;
    
    @end
    

    注:

    7、UIScreenEdgePanGestureRecognizer:屏幕边缘附近开始的平移(拖动)
    NS_CLASS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED @interface UIScreenEdgePanGestureRecognizer : UIPanGestureRecognizer
    // 手势的可接受起始边缘。
    @property (readwrite, nonatomic, assign) UIRectEdge edges;
    @end
    
    8、UILongPressGestureRecognizer:长按
    NS_CLASS_AVAILABLE_IOS(3_2) @interface UILongPressGestureRecognizer : UIGestureRecognizer
    // 点击次数 Default is 0
    @property (nonatomic) NSUInteger numberOfTapsRequired; 
    
    // 点按的手指数 Default is 1
    @property (nonatomic) NSUInteger numberOfTouchesRequired __TVOS_PROHIBITED;  
    // 最小按压时长  Default is 0.5s
    @property (nonatomic) CFTimeInterval minimumPressDuration; // Default is 0.5. Time in seconds the fingers must be held down for the gesture to be recognized
    // 默认值为10.在手势失败之前允许的最大移动像素数。
    @property (nonatomic) CGFloat allowableMovement;  
    
    @end
    

    相关文章

      网友评论

        本文标题:手势——UIGestureRecognizer

        本文链接:https://www.haomeiwen.com/subject/jgrirftx.html