日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iOS 手势UIGestureRecognizer详解

發布時間:2023/12/20 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iOS 手势UIGestureRecognizer详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、引言

在iOS系統中,手勢是進行用戶交互的重要方式,通過UIGestureRecognizer類,我們可以輕松的創建出各種手勢應用于app中。關于UIGestureRecognizer類,是對iOS中的事件傳遞機制面向應用的封裝,將手勢消息的傳遞抽象為了對象。

二、手勢的抽象類——UIGestureRecognizer

UIGestureRecognizer將一些和手勢操作相關的方法抽象了出來,但它本身并不實現什么手勢,因此,在開發中,我們一般不會直接使用UIGestureRecognizer的對象,而是通過其子類進行實例化,iOS系統給我們提供了許多用于我們實例的子類,這些我們后面再說,我們先來看一下,UIGestureRecognizer中抽象出了哪些方法。

1、統一的初始化方法

UIGestureRecognizer類為其子類準備好了一個統一的初始化方法,無論什么樣的手勢動作,其執行的結果都是一樣的:觸發一個方法,可以使用下面的方法進行統一的初始化:

- (instancetype)initWithTarget:(nullable id)target action:(nullable SEL)action;

當然,如果我們使用alloc-init的方式,也是可以的,下面的方法可以為手勢添加觸發的selector:

- (void)addTarget:(id)target action:(SEL)action;

與之相對應的,我們也可以將一個selector從其手勢對象上移除:

- (void)removeTarget:(nullable id)target action:(nullable SEL)action;

上面兩個方法是十分有意思的,因為addTarget方式的存在,iOS系統允許一個手勢對象可以添加多個selector觸發方法,并且觸發的時候,所有添加的selector都會被執行,我們以點擊手勢示例如下:

- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.UITapGestureRecognizer * ges = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(click:)];[ges addTarget:self action:@selector(haha)];[self.view addGestureRecognizer:ges]; }-(void)click:(UIGestureRecognizer *)ges{NSLog(@"第一個手勢的觸發方法"); } -(void)haha{NSLog(@"haha"); }

運行后點擊屏幕,打印如下,說明兩個方法都觸發了:

2、手勢狀態

UIGestureRecognizer類中有如下一個屬性,里面枚舉了一些手勢的當前狀態:

@property(nonatomic,readonly) UIGestureRecognizerState state;

枚舉值如下:

typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {UIGestureRecognizerStatePossible, // 默認的狀態,這個時候的手勢并沒有具體的情形狀態UIGestureRecognizerStateBegan, // 手勢開始被識別的狀態UIGestureRecognizerStateChanged, // 手勢識別發生改變的狀態UIGestureRecognizerStateEnded, // 手勢識別結束,將會執行觸發的方法UIGestureRecognizerStateCancelled, // 手勢識別取消UIGestureRecognizerStateFailed, // 識別失敗,方法將不會被調用UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded };

3、常用屬性和方法

//設置代理,具體的協議后面會說 @property(nullable,nonatomic,weak) id <UIGestureRecognizerDelegate> delegate; //設置手勢是否有效 @property(nonatomic, getter=isEnabled) BOOL enabled; //獲取手勢所在的view @property(nullable, nonatomic,readonly) UIView *view; //獲取觸發觸摸的點 - (CGPoint)locationInView:(nullable UIView*)view; //設置觸摸點數 - (NSUInteger)numberOfTouches; //獲取某一個觸摸點的觸摸位置 - (CGPoint)locationOfTouch:(NSUInteger)touchIndex inView:(nullable UIView*)view;

下面的幾個BOOL值的屬性,對于手勢觸發的控制也十分重要:

(1)

@property(nonatomic) BOOL cancelsTouchesInView;

上面的屬性默認為YES

  • 當這個屬性設置為YES時,如果識別到了手勢,系統將會發送touchesCancelled:withEvent:消息在其事件傳遞鏈上,終止觸摸事件的傳遞。
  • 設置為NO,則不會終止事件的傳遞,舉個例子來說,可能會更加清楚一些如下:
- (void)viewDidLoad {[super viewDidLoad];UIPanGestureRecognizer * ges = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(click:)];;[self.view addGestureRecognizer:ges];ges.cancelsTouchesInView=NO; } -(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{NSLog(@"123"); } -(void)click:(UIGestureRecognizer *)ges{NSLog(@"第一個手勢的觸發方法"); }

上面我們使用了拖拽手勢和touchesMoved兩個觸發方式,當我們把cancelTouchesInView設置為NO時,在屏幕上滑動,會發現兩種方式都在觸發,打印如下:

如果我們將cancelTouchesInView改為YES,當手勢觸發時,將取消觸摸消息的觸發:

(2)

@property(nonatomic) BOOL delaysTouchesBegan;

通過上面的例子,我們知道,在一個手勢觸發之前,是會一并發消息給事件傳遞鏈的,delaysTouchesBgan屬性用于控制這個消息的傳遞時機,默認這個屬性為NO,此時在觸摸開始的時候,就會發消息給事件傳遞鏈,如果我們設置為YES,在觸摸沒有被識別失敗前,都不會給事件傳遞鏈發送消息。

(3)

@property(nonatomic) BOOL delaysTouchesEnded;

這個屬性設置手勢識別結束后,是立刻發送touchesEnded消息到事件傳遞鏈或者等待一個很短的時間后,如果沒有接收到新的手勢識別任務,再發送。

4、手勢間的互斥處理

有一點需要注意,同一個View上是可以添加多個手勢對象的,默認這個手勢是互斥的,一個手勢觸發了就會默認屏蔽其他相似的手勢動作,例如:

- (void)viewDidLoad {[super viewDidLoad];// Do any additional setup after loading the view, typically from a nib.UITapGestureRecognizer * ges = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(click:)];;//view.backgroundColor = [UIColor redColor];//ges.delegate=self;[self.view addGestureRecognizer:ges];UITapGestureRecognizer * ges2 = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(click1:)]; // ges2.delegate=self;[self.view addGestureRecognizer:ges2]; }-(void)click:(UIGestureRecognizer *)ges{NSLog(@"第一個手勢的觸發方法");} -(void)click1:(UIGestureRecognizer *)ges1{NSLog(@"第二個手勢的觸發方法");}

我們添加的兩個手勢都是單擊手勢,會產生沖突,觸發是很隨機的,如果我們想設置一下當手勢互斥時要優先觸發的手勢,可以使用如下的方法:

- (void)requireGestureRecognizerToFail:(UIGestureRecognizer *)otherGestureRecognizer;

這個方法中第一個參數是需要時效的手勢,第二個是生效的手勢。

三、UIGestureRecognizerDelegate

前面我們提到過關于手勢對象的協議代理,通過代理的回調,我們可以進行自定義手勢,也可以處理一些復雜的手勢關系,其中方法如下:

//手指觸摸屏幕后回調的方法,返回NO則不再進行手勢識別,方法觸發等 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch; //開始進行手勢識別時調用的方法,返回NO則結束,不再觸發手勢 - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer; //是否支持多手勢觸發,返回YES,則可以多個手勢一起觸發方法,返回NO則為互斥 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;//****************下面這個兩個方法也是用來控制手勢的互斥執行的******* //這個方法返回YES,第一個手勢和第二個互斥時,第一個會失效 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0); //這個方法返回YES,第一個和第二個互斥時,第二個會失效 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);

四、點擊手勢——UITapGestureRecognizer

點擊手勢十分簡單,支持單擊和多次點擊,在我們手指觸摸屏幕并抬起手指時會進行觸發,其中有如下兩個屬性我們可以進行設置:

//設置點擊次數,默認為單擊 @property (nonatomic) NSUInteger numberOfTapsRequired; //設置同時點擊的手指數 @property (nonatomic) NSUInteger numberOfTouchesRequired;

五、捏合手勢——UIPinchGestureRecognizer

捏合手勢是當我們雙指捏合和擴張會觸發動作的手勢,我們可以設置的屬性如下:

//設置縮放比例 @property (nonatomic) CGFloat scale; //設置捏合速度 @property (nonatomic,readonly) CGFloat velocity;

六、拖拽手勢——UIPanGestureRecognzer

拖拽手勢是當我們點中視圖進行慢速拖拽時會觸發拖拽手勢的方法。

//設置觸發拖拽的最少觸摸點,默認為1 @property (nonatomic) NSUInteger minimumNumberOfTouches; //設置觸發拖拽的最多觸摸點 @property (nonatomic) NSUInteger maximumNumberOfTouches; //獲取當前位置 - (CGPoint)translationInView:(nullable UIView *)view; //設置當前位置 - (void)setTranslation:(CGPoint)translation inView:(nullable UIView *)view; //設置拖拽速度 - (CGPoint)velocityInView:(nullable UIView *)view;

七、滑動手勢——UISwipeGestureRecognizer

滑動手勢和拖拽手勢的不同之處在于滑動手勢更快,拖拽比較慢。

//設置觸發滑動手勢的觸摸點數 @property(nonatomic) NSUInteger numberOfTouchesRequired; //設置滑動方向 @property(nonatomic) UISwipeGestureRecognizerDirection direction; //枚舉如下 typedef NS_OPTIONS(NSUInteger, UISwipeGestureRecognizerDirection) {UISwipeGestureRecognizerDirectionRight = 1 << 0,UISwipeGestureRecognizerDirectionLeft = 1 << 1,UISwipeGestureRecognizerDirectionUp = 1 << 2,UISwipeGestureRecognizerDirectionDown = 1 << 3 };

八、旋轉手勢——UIRotationGestureRecognizer

旋轉手勢是進行旋轉動作時觸發手勢方法。

//設置旋轉角度 @property (nonatomic) CGFloat rotation; //設置旋轉速度 @property (nonatomic,readonly) CGFloat velocity;

九、長按手勢——UILongPressGestureRecognizer

長按手勢是進行長按的時候觸發的手勢方法。

//設置觸發前的點擊次數 @property (nonatomic) NSUInteger numberOfTapsRequired; //設置觸發的觸摸點數 @property (nonatomic) NSUInteger numberOfTouchesRequired; //設置最短的長按時間 @property (nonatomic) CFTimeInterval minimumPressDuration; //設置在按觸時時允許移動的最大距離 默認為10像素 @property (nonatomic) CGFloat allowableMovement;

總結

以上是生活随笔為你收集整理的iOS 手势UIGestureRecognizer详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。