一個java程式員自學IOS開發之路(十一)

來源:互聯網
上載者:User

標籤:

最近學習的進度慢了點,因為年底之前有個新項目要上線,而且每次業務人員過來一次,需求就有變動,於是不停的改改改= =!唉~不說了心好累

2015/11/29

Day 43

事件的產生和傳遞

發生觸摸事件後,系統會將該事件加入到一個由UIApplication管理的事件隊列中

 

UIApplication會從事件隊列中取出最前面的事件,並將事件分發下去以便處理,通常,先發送事件給應用程式的主視窗(keyWindow)

 

主視窗會在視圖階層中找到一個最合適的視圖來處理觸摸事件,這也是整個事件處理過程的第一步

 

找到合適的視圖控制項後,就會調用視圖控制項的touches方法來作具體的事件處理

touchesBegan…

touchesMoved…

touchedEnded…

 

UIView不接收觸摸事件的三種情況

不接收使用者互動

userInteractionEnabled = NO

隱藏

hidden = YES

透明

alpha = 0.0 ~ 0.01

提示:UIImageView的userInteractionEnabled預設就是NO,因此UIImageView以及它的子控制項預設是不能接收觸摸事件的

 

觸摸事件處理的詳細過程

使用者點擊螢幕後產生的一個觸摸事件,經過一些列的傳遞過程後,會找到最合適的視圖控制項來處理這個事件

 

找到最合適的視圖控制項後,就會調用控制項的touches方法來作具體的事件處理

touchesBegan…

touchesMoved…

touchedEnded…

 

這些touches方法的預設做法是將事件順著響應者鏈條向上傳遞,將事件交給上一個響應者進行處理

 

響應者鏈條

 

響應者鏈的事件傳遞過程

1. 如果view的控制器存在,就傳遞給控制器;如果控制器不存在,則將其傳遞給它的父視圖

2. 在視圖階層的最頂級視圖,如果也不能處理收到的事件或訊息,則其將事件或訊息傳遞給window對象進行處理

3. 如果window對象也不處理,則其將事件或訊息傳遞給UIApplication對象

4. 如果UIApplication也不能處理該事件或訊息,則將其丟棄

監聽觸摸事件的做法

如果想監聽一個view上面的觸摸事件,之前的做法是

自訂一個view

實現view的touches方法,在方法內部實現具體處理代碼

 

通過touches方法監聽view觸摸事件,有很明顯的幾個缺點

必須得自訂view

由於是在view內部的touches方法中監聽觸摸事件,因此預設情況下,無法讓其他外界對象監聽view的觸摸事件

不容易區分使用者的具體手勢行為

 

iOS 3.2之後,蘋果推出了手勢識別功能(Gesture Recognizer),在觸摸事件處理方面,大大簡化了開發人員的開發難度

UIGestureRecognizer

為了完成手勢識別,必須藉助於手勢辨識器----UIGestureRecognizer

 

利用UIGestureRecognizer,能輕鬆識別使用者在某個view上面做的一些常見手勢

 

UIGestureRecognizer是一個抽象類別,定義了所有手勢的基本行為,使用它的子類才能處理具體的手勢

UITapGestureRecognizer(敲擊)

UIPinchGestureRecognizer(捏合,用於縮放)

UIPanGestureRecognizer(拖拽)

UISwipeGestureRecognizer(輕掃)

UIRotationGestureRecognizer(旋轉)

UILongPressGestureRecognizer(長按)

 

UITapGestureRecognizer

  • 每一個手勢辨識器的用法都差不多,比如UITapGestureRecognizer的使用步驟如下
  • 建立手勢辨識器對象

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] init];

 

  • 設定手勢辨識器對象的具體屬性

// 連續敲擊2次

tap.numberOfTapsRequired = 2;

// 需要2根手指一起敲擊

tap.numberOfTouchesRequired = 2;

 

  • 添加手勢辨識器到對應的view上

[self.iconView addGestureRecognizer:tap];

 

  • 監聽手勢的觸發

[tap addTarget:self action:@selector(tapIconView:)];

 

手勢識別的狀態

typedef NS_ENUM(NSInteger, UIGestureRecognizerState) {    // 沒有觸摸事件發生,所有手勢識別的預設狀態    UIGestureRecognizerStatePossible,    // 一個手勢已經開始但尚未改變或者完成時    UIGestureRecognizerStateBegan,    // 手勢狀態改變    UIGestureRecognizerStateChanged,    // 手勢完成    UIGestureRecognizerStateEnded,    // 手勢取消,恢複至Possible狀態    UIGestureRecognizerStateCancelled,     // 手勢失敗,恢複至Possible狀態    UIGestureRecognizerStateFailed,    // 識別到手勢識別    UIGestureRecognizerStateRecognized = UIGestureRecognizerStateEnded};

然後利用UIGestureRecognizer做了一個旋轉,縮放,拖拽view的demo,操作的是一個ImageView,代碼如下

@interface ViewController () <UIGestureRecognizerDelegate>@property (weak, nonatomic) IBOutlet UIImageView *image;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    //縮放    UIPinchGestureRecognizer *pinch = [[UIPinchGestureRecognizer alloc] initWithTarget:self action:@selector(pinchView:)];    pinch.delegate = self;    [self.image addGestureRecognizer:pinch];    //旋轉    UIRotationGestureRecognizer *rotate = [[UIRotationGestureRecognizer alloc] initWithTarget:self action:@selector(rotateView:)];    rotate.delegate = self;    [self.image addGestureRecognizer:rotate];    //拖拽    UIPanGestureRecognizer *pan = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panView:)];    pan.delegate = self;    [self.image addGestureRecognizer:pan];}- (void)pinchView:(UIPinchGestureRecognizer *)pinch {    pinch.view.transform = CGAffineTransformScale(pinch.view.transform, pinch.scale, pinch.scale);    pinch.scale = 1;}- (void)rotateView:(UIRotationGestureRecognizer *)rotate {    rotate.view.transform = CGAffineTransformRotate(rotate.view.transform, rotate.rotation);    rotate.rotation = 0;}- (void)panView:(UIPanGestureRecognizer *)pan {    CGPoint translation = [pan translationInView:pan.view];    pan.view.transform = CGAffineTransformTranslate(pan.view.transform, translation.x, translation.y);    [pan setTranslation:CGPointZero inView:pan.view];} #pragma mark -代理方法/** 使所有手勢都有效 */- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {    return YES;}@end

然後是swift版的代碼

import UIKitclass ViewController: UIViewController, UIGestureRecognizerDelegate {    @IBOutlet weak var image: UIImageView!        override func viewDidLoad() {        super.viewDidLoad()        // 拖拽        let pan = UIPanGestureRecognizer(target: self, action: Selector.init("panView:"))        pan.delegate = self        self.image.addGestureRecognizer(pan)        //旋轉        let rotate = UIRotationGestureRecognizer(target: self, action: Selector.init("rotateView:"))        rotate.delegate = self        self.image.addGestureRecognizer(rotate)        //縮放        let pinch = UIPinchGestureRecognizer(target: self, action: Selector.init("pinchView:"))        pinch.delegate = self        self.image.addGestureRecognizer(pinch)    }    func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWithGestureRecognizer otherGestureRecognizer: UIGestureRecognizer) -> Bool {        return true    }    func panView(pan:UIPanGestureRecognizer) {        let translate = pan.translationInView(pan.view)        pan.view?.transform = CGAffineTransformTranslate((pan.view?.transform)!, translate.x, translate.y)        pan.setTranslation(CGPoint(x: 0, y: 0), inView: pan.view)    }    func rotateView(rotate:UIRotationGestureRecognizer) {        rotate.view?.transform = CGAffineTransformRotate((rotate.view?.transform)!, rotate.rotation)        rotate.rotation = 0    }    func pinchView(pinch:UIPinchGestureRecognizer) {        pinch.view?.transform = CGAffineTransformScale((pinch.view?.transform)!, pinch.scale, pinch.scale)        pinch.scale = 1    }}

一個java程式員自學IOS開發之路(十一)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.