天天看點

IOS開發UIGestureRecognizer的基本使用方式和代理

1,iPhone上手勢基本操作類型

 1.點選(Tap)

 點選作為最常用手勢,用于按下或選擇一個控件或條目(類似于普通的滑鼠點選)、

 2.拖動(Drag)

 拖動用于實作一些頁面的滾動,以及對控件的移動功能。

 3.滑動(Flick)

 滑動用于實作頁面的快速滾動和翻頁的功能。

 4.橫掃(Swipe)

 橫掃手勢用于激活清單項的快捷操作菜單

 5.輕按兩下(Double Tap)

 輕按兩下放大并居中顯示圖檔,或恢複原大小(如果目前已經放大)。同時,輕按兩下能夠激活針對文字編輯菜單。

 6.放大(Pinch open)

 放大手勢可以實作以下功能:打開訂閱源,打開文章的詳情。在照片檢視的時候,放大手勢也可實作放大圖檔的功能。

 7.縮小(Pinch close)

 縮小手勢,可以實作與放大手勢相反且對應的功能的功能:關閉訂閱源退出到首頁,關閉文章退出至索引頁。在照片檢視的時候,縮小手勢也可實作縮小圖檔的功能。

 8.長按(Touch &Hold)

 在我的訂閱頁,長按訂閱源将自動進入編輯模式,同時選中手指目前按下的訂閱源。這時可直接拖動訂閱源移動位置。

 針對文字長按,将出現放大鏡輔助功能。松開後,則出現編輯菜單。

 針對圖檔長按,将出現編輯菜單。

 9.搖晃(Shake)

 搖晃手勢,将出現撤銷與重做菜單。主要是針對使用者文本輸入的。

2,幾種手勢基本使用方法

#import "Gueture.h"

@interface Gueture () <UIGestureRecognizerDelegate>

@end

@implementation Gueture


- (void)viewDidLoad
{
    [super viewDidLoad];
    self.view.backgroundColor = [UIColor lightGrayColor];
    /** 建立點選一次手勢 ************************************************************/
    //1,建立一個手勢 并設定手勢的目标和觸發的事件
    UITapGestureRecognizer *tapGusture = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                 action:@selector(tapGusture:)];
    //2, 設定單擊幾次觸發這個事件
    [tapGusture setNumberOfTapsRequired:1]; //預設是1
    //3,設定幾個手指觸發這個事件
    [tapGusture setNumberOfTouchesRequired:1]; //預設是1
    //4,将這個手勢添加到主的view中
    [self.view addGestureRecognizer:tapGusture];
    
    /** 建立單擊兩次手勢 ************************************************************/
    UITapGestureRecognizer *tapGestureTwo = [[UITapGestureRecognizer alloc] initWithTarget:self
                                                                                    action:@selector(tapGustureTwo:)];
    [tapGestureTwo setNumberOfTapsRequired:2];
    [tapGestureTwo setNumberOfTouchesRequired:1];
    [self.view addGestureRecognizer:tapGestureTwo];
    //設定這個之後,兩個觸摸隻能響應一個
    [tapGusture requireGestureRecognizerToFail:tapGestureTwo];
    
    
    /** 建立捏合手勢 ************************************************************/
    //實驗發現,捏合手勢隻要兩個手指在螢幕上滑動,不管是和還是分還是旋轉都會觸發這個事件,不停的觸發
    UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGesture:)];
    [self.view addGestureRecognizer:pinchGesture];
    /*scale屬性: 可以了解為兩手指之間的距離,其實是個比例,相對距離,不是絕對距離
     以剛開始的兩個手指對應的兩個point的之間的距離為标準,此時scale=1.
     若兩手指之間距離減小,則scale不斷變小,當兩指重合,則變為0
     若兩手指之間距離變大,則scale不斷增大,沒有上限,看螢幕多大
     
     velocity屬性: 可以了解為兩手指之間的移動速度,其實是個速度比例,相對速度,不是絕對速度
     以剛開始的兩個手指對應的兩個point的之間的距離為标準,此時velocity=0.
     若兩手指之間距離減小,則velocity為負數,從-0開始,随着手指向裡捏合的速度越快,負值越大,沒有上限,我測試了下,可以到-20.009099,甚至更大 */
    
    
    /** 建立旋轉手勢 ************************************************************/
    UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationGesture:)];
    [self.view addGestureRecognizer:rotationGesture];
    [pinchGesture requireGestureRecognizerToFail:rotationGesture];//這句,當旋轉失敗時候開始執行捏合的手勢
    
    
    /** 建立長按手勢 ************************************************************/
    UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPressGesture:)];
    longPressGesture.minimumPressDuration = 1;//至少按1S才能觸發這個事件
    [self.view addGestureRecognizer:longPressGesture];
    [tapGusture requireGestureRecognizerToFail:longPressGesture];
    
    
    /** 建立快速滑動手勢 ************************************************************/
    //為什麼不太靈敏
    UISwipeGestureRecognizer *swipeGesture = [[UISwipeGestureRecognizer alloc] initWithTarget:self action:@selector(swipeGesture:)];
    [swipeGesture setDirection:UISwipeGestureRecognizerDirectionDown];//設定滑動方向向下
    [self.view addGestureRecognizer:swipeGesture];
    
    
    /** 建立 拖動慢速移動 滑動手勢 ************************************************************/
    UIPanGestureRecognizer *panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGesture:)];
    [self.view addGestureRecognizer:panGesture];
    [panGesture requireGestureRecognizerToFail:swipeGesture];
    
    
    /*
     [imageview addGestureRecognizer:singleTwo];
     imageview.multipleTouchEnabled = YES;//設定屬性使得uiimageview可以響應螢幕事件
     imageview.userInteractionEnabled = YES;
     [self.view addSubview:imageview];
     */
    
    
}
//觸摸一次 手勢處理
- (void)tapGusture:(UIGestureRecognizer *)gesture
{
    NSLog(@"tapGusture   numberOfTouches : %d", gesture.numberOfTouches);
}
//觸摸兩次 手勢處理
- (void)tapGustureTwo:(UIGestureRecognizer *)gesture
{
    NSLog(@"tapGustureTwo   numberOfTouches : %d", gesture.numberOfTouches);
}
//捏合手勢處理
- (void)pinchGesture:(UIPinchGestureRecognizer *)pinchGesture
{
    if (pinchGesture.state == UIGestureRecognizerStateBegan) {
        NSLog(@"pinchGesture start");
    }
    else if(pinchGesture.state == UIGestureRecognizerStateEnded)
    {
        NSLog(@"pinchGesture end");
    }
    else if(pinchGesture.state == UIGestureRecognizerStateChanged)
    {
        NSLog(@"pinchGesture changed");
    }
}
//旋轉手勢
- (void)rotationGesture:(UIRotationGestureRecognizer *)rotationGesture
{
    NSLog(@"rotationGesture");
}
//長按手勢
- (void)longPressGesture:(UILongPressGestureRecognizer *)longPressGesture
{
    NSLog(@"UILongPressGesture");
}
- (void)swipeGesture:(UISwipeGestureRecognizer *)swipeGesture
{
    NSLog(@"UISwipeGesture");
}
- (void)panGesture:(UIPanGestureRecognizer *)panGesture
{
    NSLog(@"UIPanGesture");
}



/*
#pragma mark - Navigation

// In a storyboard-based application, you will often want to do a little preparation before navigation
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
    // Get the new view controller using [segue destinationViewController].
    // Pass the selected object to the new view controller.
}
*/

@end
           

3,UIGestureRecognizer 和 UIGestureRecognizerDelegate

//
//  UIGestureRecognizer.h
//  UIKit
//
//  Copyright (c) 2008-2013, Apple Inc. All rights reserved.
//

#import <Foundation/Foundation.h>
#import <CoreGraphics/CoreGraphics.h>
#import <UIKit/UIKitDefines.h>

@protocol UIGestureRecognizerDelegate;
@class UIView, UIEvent, UITouch;

typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {
    UIGestureRecognizerStatePossible,   // the recognizer has not yet recognized its gesture, but may be evaluating touch events. this is the default state
    
    UIGestureRecognizerStateBegan,      // the recognizer has received touches recognized as the gesture. the action method will be called at the next turn of the run loop
    UIGestureRecognizerStateChanged,    // the recognizer has received touches recognized as a change to the gesture. the action method will be called at the next turn of the run loop
    UIGestureRecognizerStateEnded,      // the recognizer has received touches recognized as the end of the gesture. the action method will be called at the next turn of the run loop and the recognizer will be reset to UIGestureRecognizerStatePossible
    UIGestureRecognizerStateCancelled,  // the recognizer has received touches resulting in the cancellation of the gesture. the action method will be called at the next turn of the run loop. the recognizer will be reset to UIGestureRecognizerStatePossible
    
    UIGestureRecognizerStateFailed,     // the recognizer has received a touch sequence that can not be recognized as the gesture. the action method will not be called and the recognizer will be reset to UIGestureRecognizerStatePossible
    
    // Discrete Gestures – gesture recognizers that recognize a discrete event but do not report changes (for example, a tap) do not transition through the Began and Changed states and can not fail or be cancelled
    UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded // the recognizer has received touches recognized as the gesture. the action method will be called at the next turn of the run loop and the recognizer will be reset to UIGestureRecognizerStatePossible
};

NS_CLASS_AVAILABLE_IOS(3_2) @interface UIGestureRecognizer : NSObject

// Valid action method signatures:
//     -(void)handleGesture;
//     -(void)handleGesture:(UIGestureRecognizer*)gestureRecognizer;
- (id)initWithTarget:(id)target action:(SEL)action; // default initializer

- (void)addTarget:(id)target action:(SEL)action;    // add a target/action pair. you can call this multiple times to specify multiple target/actions
- (void)removeTarget:(id)target action:(SEL)action; // remove the specified target/action pair. passing nil for target matches all targets, and the same for actions

@property(nonatomic,readonly) UIGestureRecognizerState state;  // the current state of the gesture recognizer

@property(nonatomic,assign) id <UIGestureRecognizerDelegate> delegate; // the gesture recognizer's delegate

@property(nonatomic, getter=isEnabled) BOOL enabled;  // default is YES. disabled gesture recognizers will not receive touches. when changed to NO the gesture recognizer will be cancelled if it's currently recognizing a gesture

// a UIGestureRecognizer receives touches hit-tested to its view and any of that view's subviews
@property(nonatomic,readonly) UIView *view;           // the view the gesture is attached to. set by adding the recognizer to a UIView using the addGestureRecognizer: method

@property(nonatomic) BOOL cancelsTouchesInView;       // default is YES. causes touchesCancelled:withEvent: to be sent to the view for all touches recognized as part of this gesture immediately before the action method is called
@property(nonatomic) BOOL delaysTouchesBegan;         // default is NO.  causes all touch events to be delivered to the target view only after this gesture has failed recognition. set to YES to prevent views from processing any touches that may be recognized as part of this gesture
@property(nonatomic) BOOL delaysTouchesEnded;         // default is YES. causes touchesEnded events to be delivered to the target view only after this gesture has failed recognition. this ensures that a touch that is part of the gesture can be cancelled if the gesture is recognized

// create a relationship with another gesture recognizer that will prevent this gesture's actions from being called until otherGestureRecognizer transitions to UIGestureRecognizerStateFailed
// if otherGestureRecognizer transitions to UIGestureRecognizerStateRecognized or UIGestureRecognizerStateBegan then this recognizer will instead transition to UIGestureRecognizerStateFailed
// example usage: a single tap may require a double tap to fail
- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;

// individual UIGestureRecognizer subclasses may provide subclass-specific location information. see individual subclasses for details
- (CGPoint)locationInView:(UIView*)view;                                // a generic single-point location for the gesture. usually the centroid of the touches involved

- (NSUInteger)numberOfTouches;                                          // number of touches involved for which locations can be queried
- (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(UIView*)view; // the location of a particular touch

@end


@protocol UIGestureRecognizerDelegate <NSObject>
@optional
// called when a gesture recognizer attempts to transition out of UIGestureRecognizerStatePossible. returning NO causes it to transition to UIGestureRecognizerStateFailed
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;

// called when the recognition of one of gestureRecognizer or otherGestureRecognizer would be blocked by the other
// return YES to allow both to recognize simultaneously. the default implementation returns NO (by default no two gestures can be recognized simultaneously)
//
// note: returning YES is guaranteed to allow simultaneous recognition. returning NO is not guaranteed to prevent simultaneous recognition, as the other gesture's delegate may return YES
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;

// called once per attempt to recognize, so failure requirements can be determined lazily and may be set up between recognizers across view hierarchies
// return YES to set up a dynamic failure requirement between gestureRecognizer and otherGestureRecognizer
//
// note: returning YES is guaranteed to set up the failure requirement. returning NO does not guarantee that there will not be a failure requirement as the other gesture's counterpart delegate or subclass methods may return YES
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);

// called before touchesBegan:withEvent: is called on the gesture recognizer for a new touch. return NO to prevent the gesture recognizer from seeing this touch
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;

@end