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.當前視圖的位置 = 上⼀一次視圖的位置 - ⼿手指的偏移量

實現關鍵代碼:
當⼿手指在屏幕上移動時調⽤用持續調⽤用
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