iOS 個(gè)人總結(jié)-UIGestureRecognizer\響應(yīng)者鏈

作者也是前不久開始接觸iOS,若是路過的業(yè)界大佬,就此跳過吧。作者只想通過此文記錄一下最近在學(xué)習(xí)的內(nèi)容,加深印象。


一、UIResponder

以UIResponder作為超類的任何對(duì)象都可以成為響應(yīng)者。UIView以及UIViewController都是UIResponder的子類。
即UIView和UIViewcontroller及它們的子類都可以作為響應(yīng)者對(duì)象監(jiān)聽用戶手勢(shì)。

注意
UIImageView 也可以作為響應(yīng)者,前提將其屬性u(píng)serInteractionEnabled設(shè)置為YES;
imageView.userInteractionEnabled = YES;
由此注意點(diǎn),作者想到了當(dāng)一個(gè)view不能響應(yīng)事件的三種時(shí)機(jī):
userInteractionEnable = NO;hidden = YES;alpha = 0~0.01;


iOS中事件的類型:觸摸事件、加速計(jì)事件、遠(yuǎn)程控制事件

UIResponder中部分方法

//觸摸API
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
//按壓API
- (void)pressesBegan:(NSSet<UIPress *> *)presses withEvent:(nullable UIPressesEvent *)event
//加速API ?(微信搖一搖)
- (void)motionBegan:(UIEventSubtype)motion withEvent:(nullable UIEvent *)event

然后通過touches中一個(gè)方法實(shí)現(xiàn)了一個(gè)小demo
代碼:

@implementation RedView
- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    //獲取touches中的任意UITouch對(duì)象
    //一個(gè)UITouch對(duì)象代表一個(gè)手指,其生命周期從手指接觸屏幕開始到手指離開屏幕結(jié)束
    UITouch *touch = [touches anyObject];
    CGPoint curPoint = [touch locationInView:self];
    CGPoint prePoint = [touch previousLocationInView:self];
    //計(jì)算相對(duì)位移
    CGFloat sx = curPoint.x - prePoint.x;
    CGFloat sy = curPoint.y - prePoint.y;
    self.transform = CGAffineTransformTranslate(self.transform, sx, sy);
}
@end

效果圖:(實(shí)現(xiàn)redView的拖拽)


QQ20180805-201621-HD.gif

二、響應(yīng)者鏈

響應(yīng)者鏈?zhǔn)且粋€(gè)能夠響應(yīng)用戶事件的可變對(duì)象集合。

執(zhí)行機(jī)制:

如果響應(yīng)者不處理某個(gè)特殊事件,那么它通常會(huì)將事件傳遞到響應(yīng)者鏈的下一級(jí)。如果該鏈中下一個(gè)對(duì)象響應(yīng)此特殊事件,則它會(huì)處理此事件,并停止事件的傳遞過程。

當(dāng)發(fā)生一個(gè)觸摸事件后,系統(tǒng)會(huì)將事件加入到一個(gè)由UIApplication管理的事件隊(duì)列(FIFO原則)中,UIApplication會(huì)從事件中取出最前面的事件,并將事件分發(fā)下去以便處理,主穿口會(huì)在視圖層次結(jié)構(gòu)中找到一個(gè)最合適的視圖來處理觸摸事件。

注意
1.尋找最合適的響應(yīng)者是從最底層往上找的,如 window —> view —> child View
2.響應(yīng)者鏈?zhǔn)菑淖钌蠈油讓觽鬟f的,如 child view —> view —> view controller —> window —> Application

QQ20180805-205056.png

3.觸摸事件的傳遞是從父視圖傳遞給子視圖。
4.如果一個(gè)父控件不能響應(yīng)事件,則其子視圖也不能響應(yīng)事件。


三、UIGestureRecognizer

相對(duì)于上述的方法,UIGestureRecognizer實(shí)現(xiàn)手勢(shì)更加方便,不需要另外創(chuàng)建一個(gè)子類。

手勢(shì)類型

    UITapGestureRecognizer *tapGs;//點(diǎn)按手勢(shì)
    UILongPressGestureRecognizer *longPressGs;//長(zhǎng)按手勢(shì)
    UIPanGestureRecognizer *panGs;//拖動(dòng)手勢(shì)
    UISwipeGestureRecognizer *swipeGs;//輕掃手勢(shì)
    UIRotationGestureRecognizer *rotationGs;//旋轉(zhuǎn)手勢(shì)
    UIPinchGestureRecognizer *pinchGs;//捏合手勢(shì)

每種類型的手勢(shì)都有自己對(duì)應(yīng)的獨(dú)有屬性及方法,例如
UIPanGestureRecognizer中有如下(作者常用到)

- (void)setTranslation:(CGPoint)translation inView:(nullable UIView *)view;

又如UIPinchGestureRecognizer中
@property (nonatomic) CGFloat scale; //縮放比例
作者只是舉了兩個(gè)例子,在這里就不一一贅述

這里我就使用rotation手勢(shì)來實(shí)現(xiàn)一個(gè)旋轉(zhuǎn)(rotation):
代碼:

- (void)viewDidLoad {
    [super viewDidLoad];
    self.pinkView.userInteractionEnabled  = YES;
    UIRotationGestureRecognizer *rotationGs = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationAction:)];
    [self.pinkView addGestureRecognizer:rotationGs];
}
- (void)rotationAction:(UIRotationGestureRecognizer *)rotationGs {
    self.pinkView.transform = CGAffineTransformRotate(self.pinkView.transform, rotationGs.rotation);
    //注意要重制rotation為0,否則rotation會(huì)累計(jì)
    [rotationGs setRotation:0];
}

效果圖:(實(shí)現(xiàn)ImageView旋轉(zhuǎn))


旋轉(zhuǎn)手勢(shì).gif

四、UIGestureRecognizerDelegate

作者也只是列出了協(xié)議中的部分方法

//是否監(jiān)聽手勢(shì)
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;

// 是否允許同時(shí)支持多個(gè)手勢(shì),默認(rèn)是不支持多個(gè)手勢(shì)
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;

// 手指觸摸屏幕后回調(diào)的方法,手勢(shì)識(shí)別
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch;

注意
iOS中默認(rèn)是不支持多個(gè)手勢(shì),若要實(shí)現(xiàn)多個(gè)手勢(shì),就要實(shí)現(xiàn)UIRegestureRecognizerDelegate中的一個(gè)方法

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
        return YES;
}

這里,我就用協(xié)議使用了兩個(gè)手勢(shì)
(代碼差不多,就不上了)
效果:


旋轉(zhuǎn)&平移.gif

這是我的第一篇文,知識(shí)偏基礎(chǔ)、簡(jiǎn)單,主要是想體驗(yàn)下寫文的方式,了解下markdown語法的使用,制作gif,制作概念圖,同時(shí)也記錄一下自己學(xué)習(xí)的內(nèi)容。
自己所在工作室的師兄都很厲害,向他們學(xué)習(xí)hiahiahiahia。

文中若有知識(shí)漏洞,還請(qǐng)路過的讀者指正,謝謝~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

友情鏈接更多精彩內(nèi)容