你好,歡迎來到IOS教程網

 Ios教程網 >> IOS訊息 >> 關於IOS >> iOS開發學習之觸摸事件和手勢識別

iOS開發學習之觸摸事件和手勢識別

編輯:關於IOS

iOS的輸入事件

觸摸事件 手勢識別 手機搖晃 一、iOS的輸入事件   觸摸事件(滑動、點擊) 運動事件(搖一搖、手機傾斜、行走),不需要人為參與的 遠程控制事件(耳機控制手機聲音) 1⃣️iOS事件對象都是UIEvent類的實例 UIEvent類對事件類型定義了enum常量: typedef NS_ENUM(NSInteger, UIEventType){      UIEventTypeTouches,      UIEventTypeMotion,      UIEventRemoteControl, }; 觸摸事件必須是繼承UIResponser的 二、觸摸事件 1⃣️UIView,有4種處理不同的觸摸事件 UIView是UIResponder的子類,可以覆蓋下列4個方法處理不同的觸摸事件。 1. 一根或者多根手指開始觸摸屏幕 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 2.一根或者多根手指在屏幕上移動(隨著手指的移動,會持續調用該方法) - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 3.一根或者多根手指離開屏幕 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 4.觸摸結束前,某個系統事件(例如電話呼入)會打斷觸摸過程 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event 復制代碼 #pragma mark - UITouch事件 #pragma mark 觸摸開始 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {     NSLog(@"觸摸開始");     for (UITouch *touch in touches) {         NSLog(@"%@", touch);     } }   #pragma mark 觸摸移動 - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {     NSLog(@"觸摸移動Touch對象個數:%d",[touches count]);     // 要移動界面上黃顏色的視圖          // 1. 得到當前手指的位置     UITouch *touch = [touches anyObject];     CGPoint location = [touch locationInView:self.view];     // 2. 得到上一次手指的位置     CGPoint preLocation = [touch previousLocationInView:self.view];     // 3. 計算兩個位置之間的偏移     CGPoint offset = CGPointMake(location.x - preLocation.x, location.y - preLocation.y);     // 4. 使用計算出來的偏移量,調整視圖的位置     [_demoView setCenter:CGPointMake(_demoView.center.x + offset.x, _demoView.center.y + offset.y)];          // 完整的UITouch事件調試方法     NSLog(@"觸摸移動");     for (UITouch *touch in touches) {         NSLog(@"%@", touch);     } }   #pragma mark 觸摸結束 - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {     // 完整的UITouch事件調試方法     NSLog(@"觸摸完成");     for (UITouch *touch in touches) {         NSLog(@"%@", touch);     } }   #pragma mark 觸摸中斷 - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {     // 完整的UITouch事件調試方法     NSLog(@"觸摸中斷");     for (UITouch *touch in touches) {         NSLog(@"%@", touch);     } } 復制代碼 2⃣️觸摸事件的處理 如果hit-test視圖無法處理事件,則通過響應者鏈向上傳遞 1.如果hit-test視圖的控制器存在,就傳遞給控制器;如果控制器不存在,則將其傳遞給它的父視圖 2.如果視圖或它的控制器無法處理收到的事件或消息,則將其傳遞給該視圖的父視圖 3.每一個在視圖繼承樹中的上層視圖如果不能處理收到的事件或消息,則重復上面的步驟1,2 4.在視圖繼承樹的最上層視圖,如果也不能處理收到的事件或消息,則其將事件或消息傳遞給窗口對象進行處理 5. 如果窗口對象也不能進行處理,則其將事件或消息傳遞給UIApplication對象 6.如果UIApplication也不能處理該事件或消息,則將其丟棄 當用戶點擊屏幕時,會產生一個UITouch對象傳遞給UIApplication,然後由window負責查找最適合相應觸摸事件的視圖對象(hitTest,pointInside) 找到合適的視圖之後,Touch方法由對應的視圖完成,上級視圖不再接管 3⃣️不接受處理事件的三種方法 不接收用戶交互:userInteractionEnabled = NO; 隱藏:hidden = YES; 透明:alpha = 0~0.01 三、手勢識別 1⃣️iOS目前支持的手勢識別(6種) UITapGestureRecognizer(點按) UIPinchGestureRecognizer(捏合) UIPanGestureRecognizer(拖動) UISwipeGestureRecognizer(輕掃) UIRotationGestureRecognizer(旋轉) UILongPressGestureRecognizer(長按) 2⃣️手勢識別的使用方法(4步) 通常在視圖加載的時候定義(UIGestureRecognizer是抽象類,需要實例化使用) 創建手勢識別實例 設置手勢識別屬性,例如手指數量,方向等 將手勢識別附加到指定的視圖之上 編寫手勢觸發響應方法 3⃣️手勢識別的狀態(7個)    1.  // 沒有觸摸事件發生,所有手勢識別的默認狀態     UIGestureRecognizerStatePossible,     // 一個手勢已經開始但尚未改變或者完成時     UIGestureRecognizerStateBegan,     // 手勢狀態改變     UIGestureRecognizerStateChanged,     // 手勢完成     UIGestureRecognizerStateEnded,     // 手勢取消,恢復至Possible狀態     UIGestureRecognizerStateCancelled,      // 手勢失敗,恢復至Possible狀態     UIGestureRecognizerStateFailed,     // 識別到手勢識別     UIGestureRecognizerStateRecognized =UIGestureRecognizerStateEnded    2.手勢識別的屬性 state——手勢狀態 view——手勢發生視圖 常用方法 locationInView 獲得手勢發生對應視圖所在位置 復制代碼 - (void)viewDidLoad {     [super viewDidLoad];     /**      1. 演示點按手勢      */     // 根據實例化方法,我們知道:     // 1.有一個處理消息的對象,應該是self     // 2.我們需要定義一個方法,當手勢識別檢測到的時候,運行     UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(tapAction:)];     // setNumberOfTapsRequired 點按次數     [tap setNumberOfTapsRequired:1];     // setNumberOfTouchesRequired 點按的手指數量     [tap setNumberOfTouchesRequired:1];     // 把手勢識別增加到視圖上     [self.demoView addGestureRecognizer:tap];          /**      2. 捏合點按手勢      */     UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc]initWithTarget:self action:@selector(pinchAction:)];     [self.demoView addGestureRecognizer:pinch];          /**      3. 旋轉點按手勢      */     UIRotationGestureRecognizer *rotation = [[UIRotationGestureRecognizer alloc]initWithTarget:self action:@selector(rotationAction:)];     [self.demoView addGestureRecognizer:rotation];          /**      4. 拖放點按手勢      */     UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(panAction:)];     [self.demoView addGestureRecognizer:pan];          /**      5. 長按手勢      */     UILongPressGestureRecognizer *longPress = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(longPressAction:)];     [self.demoView addGestureRecognizer:longPress];          /**      6. 輕掃手勢      關於輕掃手勢,是需要指定方向的,如果你不指定方向,那麼只能接收到的向右方向的輕掃事件      */     // 向左掃     UISwipeGestureRecognizer *swipeLeft = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];     [swipeLeft setDirection:UISwipeGestureRecognizerDirectionLeft];     [self.view addGestureRecognizer:swipeLeft];     // 向右掃     UISwipeGestureRecognizer *swipeRight = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];     [swipeRight setDirection:UISwipeGestureRecognizerDirectionRight];     [self.view addGestureRecognizer:swipeRight];     // 向上掃     UISwipeGestureRecognizer *swipeTop = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];     [swipeTop setDirection:UISwipeGestureRecognizerDirectionUp];     [self.view addGestureRecognizer:swipeTop];     // 向下掃     UISwipeGestureRecognizer *swipeDown = [[UISwipeGestureRecognizer alloc]initWithTarget:self action:@selector(swipeAction:)];     [swipeDown setDirection:UISwipeGestureRecognizerDirectionDown];     [self.view addGestureRecognizer:swipeDown]; }   - (void)didReceiveMemoryWarning {     [super didReceiveMemoryWarning];     // Dispose of any resources that can be recreated. }   #pragma mark - 輕掃手勢 - (void)swipeAction:(UISwipeGestureRecognizer *)sender {     NSLog(@"%d", sender.direction);     switch (sender.direction) {         case UISwipeGestureRecognizerDirectionLeft:             NSLog(@"向左掃");             break;         case UISwipeGestureRecognizerDirectionRight:             NSLog(@"向右掃");             break;         case UISwipeGestureRecognizerDirectionUp:             NSLog(@"向上掃");             break;         case UISwipeGestureRecognizerDirectionDown:             NSLog(@"向下掃");             break;         default:             break;     } }   #pragma mark - 長按手勢 - (void)longPressAction:(UILongPressGestureRecognizer *)sender {     // 我們可以利用demoView的Tag屬性,默認時tag=0     // 如果tag=0,我們放大一倍,否則,我們縮小一半     CGFloat scale;     if (_demoView.tag == 0) {         scale = 2.0;         _demoView.tag = 1;     } else {         scale = 0.5;         _demoView.tag = 0;     }          sender.view.transform = CGAffineTransformScale(sender.view.transform, scale, scale); }   #pragma mark - 拖放手勢 - (void)panAction:(UIPanGestureRecognizer *)sender {     // 在拖放手勢中是需要考慮手指的狀態的UIGestureRecognizerState     // 在拖放手勢中使用的狀態是UIGestureRecognizerStateChanged     // 通常在使用拖放手勢的時候,當手指離開的時候,應該做一個很小的動作,提醒用戶拖放完成     if (sender.state == UIGestureRecognizerStateChanged) {         // locationInView         [_demoView setCenter:[sender locationInView:self.view]];     } else if (sender.state == UIGestureRecognizerStateEnded) {         [_demoView setBackgroundColor:[UIColor yellowColor]];     } }   #pragma mark - 旋轉手勢 - (void)rotationAction:(UIRotationGestureRecognizer *)sender {     sender.view.transform = CGAffineTransformRotate(sender.view.transform, sender.rotation);          // 和捏合操作類似,旋轉角度同樣需要方福偉     sender.rotation = 0.0f; }   #pragma mark - 捏合手勢 - (void)pinchAction:(UIPinchGestureRecognizer *)sender {     // 有關轉換的內容,我們在後續動畫部分再繼續     sender.view.transform = CGAffineTransformScale(sender.view.transform, sender.scale, sender.scale);          // 縮放功能很簡單,但是不要忘記將比例復位     sender.scale = 1.0f;     NSLog(@"捏我了"); }   #pragma mark - 點按手勢 - (void)tapAction:(UITapGestureRecognizer *)sender {     /**      在開發過程中,如果沒有什麼必要,最好不要對一個UI控件,既使用觸摸,又使用手勢。      */     NSLog(@"點我了 %@", sender); }   #pragma mark - 手勢觸摸事件 - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {     NSLog(@"觸摸事件!");     // 1. 先取出UITouch對象     // 2. 判斷響應點擊的UIView是不是我們需要的     UITouch *touch = [touches anyObject];     if ([touch view] == _imageView) {         NSLog(@"點到圖像了!");     } } 復制代碼 四、手機搖晃 1. 新建搖晃監聽視圖ShakeListenerView,並且設置canBecomeFirstResponder返回YES - (BOOL)canBecomeFirstResponder {     return YES; } 2. 在Storyboard中將ViewController的View的Class設置為:ShakeListenerView 3. 在ViewController.m文件中增加:viewDidAppear和viewDidDisappear在視圖出現和消失時成為/撤銷第一響應者身份 4. 在視圖控制器中增加手勢監聽方法: - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {     if (event.subtype == UIEventSubtypeMotionShake) {         NSLog(@"shake phone");     } } 復制代碼 #pragma mark - 要讓ViewController支持搖晃,需要寫三個方法 // 1. 成為第一響應者,視圖一出現時,就應該成為第一響應者 - (void)viewDidAppear:(BOOL)animated {     [self.view becomeFirstResponder];     // 不要忘記去實現父類方法     [super viewDidAppear:animated]; }   // 2. 注銷第一響應者,視圖要關閉的時候,注銷 - (void)viewDidDisappear:(BOOL)animated {     [self.view resignFirstResponder];     // 不要忘記去實現父類方法     [super viewDidDisappear:animated]; }   // 3. 監聽並處理移動事件,判斷是否搖晃了手機 - (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event {     if (motion == UIEventSubtypeMotionShake) {         NSLog(@"搖啊搖,搖到外婆橋!!!");     } }
  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved