UI高級03-觸摸事件 搖一搖 部分手勢 控件不響應(yīng)處理

搖一搖的相關(guān)事件, 都是從UIResponder中繼承過來的

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    NSLog(@"開始搖一搖");
}
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
   NSLog(@"結(jié)束搖一搖");
}
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event
{
    // 如來電
    NSLog(@"搖一搖被取消");
}

觸摸開始, 手指按下去 (沒有松開)
在一次手勢觸摸的過程(從按下到松開), 只執(zhí)行一次

- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

觸摸后開始移動, 手指按下后還沒有松開, 然后開始移動 (手指還沒有離開屏幕)
在一次手勢觸摸的過程(從按下到松開), 會執(zhí)行很多次

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

觸摸結(jié)束, 手指離開了屏幕了

- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

觸摸取消, 如來電

- (void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

獲取當前的觸摸點

UITouch *touch = [touches anyObject];

獲取當前觸摸的點在self.view上的位置 如果移動也會一直變動

CGPoint point = [touch locationInView:self.view];

獲取觸摸屏幕時記錄的點 只記錄觸摸的一瞬間

CGPoint prePoint = [touch previousLocationInView:self.view];

視圖默認只支持一個點的, 如果要支持多點的觸摸, 需要額外配置 添加以下代碼

 [self.view setMultipleTouchEnabled:YES];

示例:

以下方法實現(xiàn)后 添加視圖素材 可以實現(xiàn)觸摸屏幕的同時 觸摸的地方顯示素材光點

- (void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSArray<UITouch *> *touchArr = [touches allObjects];
    
    for (UITouch *touch in touchArr) {
        // -------- 2. 獲取該獲取點在根視圖上的位置 --------
        CGPoint point = [touch locationInView:self.view];
        NSLog(@"%@", NSStringFromCGPoint(point));

        // -------- 3. 添加UIImage控件 --------
        UIImage *image = [UIImage imageNamed:@"spark_green"];
        UIImageView *imageview = [[UIImageView alloc] initWithImage:image];
        imageview.center = point;
        [self.view addSubview:imageview];

        // -------- 4. 逐漸消失的動畫, 動畫完之后移除 --------
        [UIView animateWithDuration:2.0 animations:^{
            imageview.alpha = 0.0;
        } completion:^(BOOL finished) {
            [imageview removeFromSuperview];
        }];
    }

遍歷集合數(shù)據(jù)類型中的每個元素

     stop是BOOL *類型, 表示的是指向BOOL類型值的指針
   [touches enumerateObjectsUsingBlock:^(UITouch *obj, BOOL* stop) {
        // 每一次Block的執(zhí)行, 都是集合中某一個元素的遍歷操作
        NSLog(@"helloWord: %@", obj);
        
        // 當你找到需要的那個對象時, stop可以讓遍歷操作停下來
        // 將stop所指向的那個BOOL類型的值改成YES
        * stop = YES;
    }];
}

控件不響應(yīng)的情況

  1. 控件的用戶交互被關(guān)閉, 無法響應(yīng)事件
    • setUserInteractionEnabled
    • 如果父視圖不能響應(yīng)事件, 子控件也不能響應(yīng)事件
    • 響應(yīng)者鏈條在父控件上斷開
  2. 控件看不見時, 不能響應(yīng)事件
    • 被隱藏, hidden
    • 透明度太小, <=0.01 (太透明, 跟沒有一樣)
  3. 觸摸的點不在控件的有限范圍之內(nèi)
    • 子控件如果超出了父控件的范圍, 那部分就不屬于子控件的有限范圍
    • 當超出部分沒有被裁剪時, 會看得到超出的那部分范圍, 但是它不會響應(yīng)事件

超出父控件部分要裁剪

self.view.clipsToBounds = YES;

多點觸摸:

  1. 視圖默認支持1個點, 要啟用多點支持, 額外配置
[self.view setMultipleTouchEnabled:YES];
  1. 集合的遍歷, anyObject是任意的一個對象
    • 取出全部的集合對象 allObjects
    • 使用block遍歷的方式 (數(shù)組, 字典, 集合)

** 響應(yīng)事件觸發(fā)時的調(diào)用堆棧**

  1. 運行循環(huán) (檢測整個應(yīng)用的觸摸事件) (死循環(huán))
  2. 向UIApplication發(fā)送消息
  3. UIApplication向UIWindow (keyWindow)發(fā)送消息
  4. 依據(jù)響應(yīng)者鏈條, 遞歸的讓所有子視圖都檢測 (找出最終響應(yīng)該事件的控件)
    • 如果找到了, 最終會傳遞回UIApplication, 再來執(zhí)行相關(guān)的事件調(diào)用
    • 如果找不到, 最終也會傳遞回UIApplication, 由于沒有控件能響應(yīng), 本次觸摸結(jié)束

** 響應(yīng)者鏈條**

  1. UIWindow 向下級傳遞, window的根控制器, 它的根視圖
    • 如果下級視圖, 是某個控制器的根視圖, 會先傳遞給控制器, 再由控制器傳遞給根視圖
  2. 視圖會先檢查其子視圖是否能夠響應(yīng)事件
    • 每個視圖, 都會優(yōu)先檢查子視圖是否能響應(yīng)
    • 檢查完所有子視圖, 再檢查

使用hitTest方法來進行鏈條的傳遞

  • hitTest的返回值
  • null本次的傳遞當中, 沒有發(fā)現(xiàn)對應(yīng)的控件
  • UIView實例, 意味著找到響應(yīng)的控件, 逆著鏈條將結(jié)果傳遞回去
  • pointInside: withEvent:

傳遞響應(yīng)連接的關(guān)鍵方法
返回值:

  • 如果沒有在響應(yīng)范圍之內(nèi), 是null
  • 如果是當前視圖的響應(yīng), 返回自己
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
UIView *view = [super hitTest:point withEvent:event];
    NSLog(@"紅色視圖 - : %@", view);
    
    return view;
};

該方法判斷觸摸點是否在本控件有限范圍之內(nèi), 返回結(jié)果
hitTest默認是使用pointInSide來檢測觸摸點是否為本控件來響應(yīng)

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event
{
BOOL result = [super pointInside:point withEvent:event];
    NSLog(@"%@", result ? @"觸摸點在紅色控件的范圍之內(nèi)" : @"不在范圍內(nèi)");
    
    return result;
};

手勢

UIImageView的坑點
UIImageView默認不支持用戶交互, 手勢不能用(觸摸事件)
SB中有配置用戶交互的選項
UIImageView在SB中當中, 是不給添加子視圖

** UIGestureRecognizer 是所有具體手勢的抽象類**
手勢在SB|Xib當中都提供了對應(yīng)的控件
可以拖拽使用, 手勢是針對控件而言, 往哪個控件身上拖拽, 就是向哪個控件添加手勢
可以直接在SB當中, 為手勢添加對應(yīng)的響應(yīng)事件
一個控件是可以同時添加多個手勢, 各自響應(yīng)自己的事件

  1. 可以將兩個手勢同時添加到一個控件里
    • 控件可以響應(yīng)兩個手勢, 單獨響應(yīng)
  2. 允許兩個手勢同時響應(yīng) (默認不能允許)
    • 在一次觸摸事件的過程當中, 兩個手勢是可以同時來響應(yīng)
    • 通過UIGestureRecognizerDelegate方法來幫助實現(xiàn)

以下是部分手勢添加示例 但是要手勢有反應(yīng) 需要實現(xiàn)方法(為手勢添加方法)

捏合手勢

Pinch 捏合手勢 (放大縮小) UIPinchGestureRecognizer

  1. 實例化手勢, 綁定觸發(fā)的事件
UIPinchGestureRecognizer *pinchGesture = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchGestureAction:)];
    pinchGesture.delegate = self;
  1. 將手勢添加到某個視圖當中
[self.imageView addGestureRecognizer:pinchGesture];

撮合手勢的響應(yīng)事件件(就是添加的方法 上面只是添加了手勢 但是手勢之后會怎樣響應(yīng)需要自行實現(xiàn))
需要兩個觸摸點, 多點觸摸的支持 (視圖默認只支持一個點)
如果不能使用, 就打開多點觸摸的配置
** 該響應(yīng)事件會觸發(fā)多次, (多個階段)**

-(void)pinchGestureAction:(UIPinchGestureRecognizer *)sender
{
   // scale 縮放比例 (兩個點之間的距離變化)
   NSLog(@"%f, %zd", sender.scale, sender.numberOfTouches);
   
   // -------- 讓圖片跟隨捏合進行放大縮小 --------
   // 1. 獲取到縮放值
   // 2. 利用Transform來進行放大縮小
   self.imageView.transform = CGAffineTransformScale(sender.view.transform, sender.scale, sender.scale);
   
   // 重圍scale初始計算值
   sender.scale = 1.0;
}

旋轉(zhuǎn)手勢

UIRotationGestureRecognizer *rotationGesture = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotationGestureAction:)];
    rotationGesture.delegate = self;
[self.imageView addGestureRecognizer:rotationGesture];

旋轉(zhuǎn)手勢的響應(yīng)事件(就是添加的方法 上面只是添加了手勢 但是手勢之后會怎樣響應(yīng)需要自行實現(xiàn))

- (void)rotationGestureAction:(UIRotationGestureRecognizer *)sender
{
    // 旋轉(zhuǎn)的值的大小, 是弧度值
    NSLog(@"%f", sender.rotation);
    
    // 應(yīng)用旋轉(zhuǎn)
    sender.view.transform = CGAffineTransformRotate(sender.view.transform, sender.rotation);
    
    // 重置旋轉(zhuǎn)的值的初始計算
    sender.rotation = 0;
}

如果需要同時響應(yīng)多個手勢事件 需要實現(xiàn)以下方法 并遵守UIGestureRecognizerDelegate協(xié)議

返回是否允許多個手勢識別器同時識別各自的事件

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    return YES;
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蓖康,一起剝皮案震驚了整個濱河市串述,隨后出現(xiàn)的幾起案子陋气,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件世杀,死亡現(xiàn)場離奇詭異遂鹊,居然都是意外死亡飞袋,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評論 2 385
  • 文/潘曉璐 我一進店門句各,熙熙樓的掌柜王于貴愁眉苦臉地迎上來吸占,“玉大人,你說我怎么就攤上這事凿宾》停” “怎么了?”我有些...
    開封第一講書人閱讀 156,780評論 0 346
  • 文/不壞的土叔 我叫張陵初厚,是天一觀的道長件蚕。 經(jīng)常有香客問我,道長产禾,這世上最難降的妖魔是什么骤坐? 我笑而不...
    開封第一講書人閱讀 56,388評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮下愈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘蕾久。我一直安慰自己势似,他們只是感情好,可當我...
    茶點故事閱讀 65,430評論 5 384
  • 文/花漫 我一把揭開白布僧著。 她就那樣靜靜地躺著履因,像睡著了一般。 火紅的嫁衣襯著肌膚如雪盹愚。 梳的紋絲不亂的頭發(fā)上栅迄,一...
    開封第一講書人閱讀 49,764評論 1 290
  • 那天,我揣著相機與錄音皆怕,去河邊找鬼毅舆。 笑死西篓,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的憋活。 我是一名探鬼主播岂津,決...
    沈念sama閱讀 38,907評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼悦即!你這毒婦竟也來了吮成?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評論 0 266
  • 序言:老撾萬榮一對情侶失蹤辜梳,失蹤者是張志新(化名)和其女友劉穎粱甫,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體作瞄,經(jīng)...
    沈念sama閱讀 44,122評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡茶宵,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,459評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了粉洼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片节预。...
    茶點故事閱讀 38,605評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖属韧,靈堂內(nèi)的尸體忽然破棺而出安拟,到底是詐尸還是另有隱情,我是刑警寧澤宵喂,帶...
    沈念sama閱讀 34,270評論 4 329
  • 正文 年R本政府宣布糠赦,位于F島的核電站,受9級特大地震影響锅棕,放射性物質(zhì)發(fā)生泄漏拙泽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,867評論 3 312
  • 文/蒙蒙 一裸燎、第九天 我趴在偏房一處隱蔽的房頂上張望顾瞻。 院中可真熱鬧,春花似錦德绿、人聲如沸荷荤。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蕴纳。三九已至,卻和暖如春个粱,著一層夾襖步出監(jiān)牢的瞬間古毛,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評論 1 265
  • 我被黑心中介騙來泰國打工都许, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留稻薇,地道東北人嫂冻。 一個月前我還...
    沈念sama閱讀 46,297評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像颖低,于是被迫代替她去往敵國和親絮吵。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 43,472評論 2 348

推薦閱讀更多精彩內(nèi)容

  • 在iOS開發(fā)中經(jīng)常會涉及到觸摸事件忱屑。本想自己總結(jié)一下蹬敲,但是遇到了這篇文章,感覺總結(jié)的已經(jīng)很到位莺戒,特此轉(zhuǎn)載伴嗡。作者:L...
    WQ_UESTC閱讀 5,995評論 4 26
  • 好奇觸摸事件是如何從屏幕轉(zhuǎn)移到APP內(nèi)的?困惑于Cell怎么突然不能點擊了从铲?糾結(jié)于如何實現(xiàn)這個奇葩響應(yīng)需求瘪校?亦或是...
    Lotheve閱讀 56,806評論 51 597
  • -- iOS事件全面解析 概覽 iPhone的成功很大一部分得益于它多點觸摸的強大功能,喬布斯讓人們認識到手機其實...
    翹楚iOS9閱讀 2,947評論 0 13
  • 概覽iPhone的成功很大一部分得益于它多點觸摸的強大功能振湾,喬布斯讓人們認識到手機其實是可以不用按鍵和手寫筆直接操...
    紙簡書生閱讀 1,436評論 0 6
  • 她是一個非成奔#可愛的博美犬,她到來的那一天是二零十六年正月初八押搪,取名為初八佛南。 她來的那一天,身體又臟又臭嵌言,而且后...
    聾美閱讀 666評論 1 2