ios開發事件處理之:一:UIView的拖拽


1.ios當中常⽤的事件?  觸摸事件 ,加速計事件 ,遠程控制事件

2.什么是響應者對象? 繼承了UIResponds的對象我們稱它為響應者對象 UIApplication、UIViewController、UIView都繼承⾃自UIResponder 因此它們都是響應者對象,都能夠接收並處理事件

3.為什么說繼承了UIResponder就能夠處理事件? 因為UIResponder內部提供了以下⽅方法來處理事件 ⽐比如

  觸摸事件會調⽤用以下⽅方法:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event;
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

 

 加速計事件會調⽤用:

- (void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event;
- (void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event; 遠程控制事件會調⽤用:
- (void)remoteControlReceivedWithEvent:(UIEvent *)event;

4.如何監聽UIView的觸摸事件? 想要監聽UIViiew的觸摸事件,⾸首先第⼀一步要⾃自定義UIView, 因為只有實現了UIResponder的事件⽅方法才能夠監聽事件.

UIView的觸摸事件主要有:

⼀一根或者多根⼿手指開始觸摸view,系統會⾃自動調⽤用view的下⾯面⽅方法.

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

⼀一根或者多根⼿手指在view上移動時,系統會⾃自動調⽤用view的下⾯面⽅方法 (隨着⼿手指的移動,會持續調⽤用該⽅方法,也就是說這個⽅方法會調⽤用很多次)

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

⼀一根或者多根⼿手指離開view,系統會⾃自動調⽤用view的下⾯面⽅方法
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

⼀一當突然發生系統事件的時候,例如突然來了系統電話,或是手機沒電的時候,系統就會自動調用

- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event;

 

參數說明:

    touches:

    touches中存放的都是UITouch對象,它是一個NSSet集合.NSSet和NSArray一樣同樣屬於集合,但是NSSet是無序的,NSArray是有序的,有序的就可以通過index將對象從集合中取出

    UITouch對象它就是用來保存手指相關聯的信息.包括位置,時間,階段等信息.

    每一個手指對應着一個UITouch對象.

    這個UITouch是系統自動幫我們創建的,當手指移動時,系統會更新同一個UITouch對象,

    使它能夠一直保存該手指在的觸摸位置

    

    通過獲取UITouch屬性,我們可以獲得觸摸產生時所處的窗口,觸摸的View,時間,點擊的次數等,

    這些都可以在通過UITouch獲取.

   

 UITouch方法:

@property(nonatomic,readonly) NSTimeInterval      timestamp;//獲取點擊的時間

@property(nonatomic,readonly) UITouchPhase        phase;//點擊的狀態

@property(nonatomic,readonly) NSUInteger          tapCount;   //點擊的次數

@property(nullable,nonatomic,readonly,strong) UIWindow  *window;//點擊的所在的window

@property(nullable,nonatomic,readonly,strong) UIView *view;//點擊所在的view

    event:

    還可以通過UITouch提供的方法獲取當前手指所在的點,以及上一個手指所在的點.

    取當前手指所在的點

    - (CGPoint)locationInView:(UIView *)view;

    獲取上一個觸摸點的位置.

    - (CGPoint)previousLocationInView:(UIView *)view;

     每產生一個事件,就會產生一個UIEvent對象

    UIEvent:稱為事件對象,記錄事件產生的時刻和類型

 一次完整的觸摸過程,會經歷3個狀態:

觸摸開始:- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

觸摸移動:- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

觸摸結束:- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

觸摸取消(可能會經歷):- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

一次完整的觸摸過程中,只會產生一個事件對象,4個觸摸方法都是同一個event參數

如果兩根手指同時觸摸一個view,那么view只會調用一次touchesBegan:withEvent:方法,touches參數中裝着2個UITouch對象

如果這兩根手指一前一后分開觸摸同一個view,那么view會分別調用2次touchesBegan:withEvent:方法,

並且每次調用時的touches參數中只包含一個UITouch對象

 

5. UIView拖拽思路?
1.⾃自定義UIView,實現監聽⽅方法. 2.確定在TouchMove⽅方法當中進⾏行操作,因為⽤用戶⼿手指在視圖上移動的時候才需要移動視 圖。
3.獲取當前⼿手指的位置和上⼀一個⼿手指的位置.
4.當前視圖的位置 = 上⼀一次視圖的位置 - ⼿手指的偏移量

page2image376

實現關鍵代碼:
當⼿手指在屏幕上移動時調⽤用持續調⽤用
NSSet:⾥里⾯面的元素都是⽆無序的.
NSArray:⾥里⾯面的有順序的.
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{

1.獲取⼿手指的對象
UITouch *touch = [touches anyObject];

2.獲取當前⼿手指所在的點.
CGPoint curP = [touch locationInView:self]; 3.獲取⼿手指的上⼀一個點.

CGPoint preP = [touch previousLocationInView:self]; X軸⽅方向偏移量

CGFloat offsetX = curP.x - preP.x; Y軸⽅方向偏移量

CGFloat offsetY = curP.y - preP.y; CGAffineTransformMakeTranslation:會清空上⼀一次的形變. self.transform = CGAffineTransformMakeTranslation(offsetX,

0);

self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY);

 

#import "RedView.h"

@implementation RedView


//當開始觸摸屏幕的時候調用
-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSLog(@"%s",__func__);
}

//觸摸時開始移動時調用(移動時會持續調用)


/*
 
  1:touches.allObjects:獲得所有的觸摸的手指UITouch對象:當只有一根手指觸摸屏幕就會產生一個UITouch對象,一個UITouch對象通過[touches anyObject]獲得
  2: CGPoint curP = [touch locationInView:self];
     CGPoint preP = [touch previousLocationInView:self];
  3:要累加形變:所以用CGAffineTransformTranslate(self.transform, offsetX, offsetY),初始狀態self.transform為0
 */
//NSSet:無序
//NSArray:有序
-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    
    //做UIView拖拽
    UITouch *touch = [touches anyObject];
   
    
    //求偏移量 = 手指當前點的X - 手指上一個點的X
    CGPoint curP = [touch locationInView:self];
    CGPoint preP = [touch previousLocationInView:self];
    NSLog(@"curP====%@",NSStringFromCGPoint(curP));
    NSLog(@"preP====%@",NSStringFromCGPoint(preP));
    
    CGFloat offsetX = curP.x - preP.x;
    CGFloat offsetY = curP.y - preP.y;
    
    //平移
    self.transform = CGAffineTransformTranslate(self.transform, offsetX, offsetY);
    
}

//當手指離開屏幕時調用
-(void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
     NSLog(@"%s",__func__);
}


//當發生系統事件時就會調用該方法(電話打入,自動關機)
-(void)touchesCancelled:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
     NSLog(@"%s",__func__);
}



@end

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM