我們經常在IPhone中涉及到開發通過觸摸移動自己的按鈕或視圖。例如下面3個圖:通過手指觸控螢幕幕移動灰色按鈕:
下面具體講解一下實現此效果的過程:
1.首先我們自訂一個按鈕MyButton 繼承自UIButton
#import <UIKit/UIKit.h>@interface MyButton : UIButton{ CGFloat xDistance; //觸摸點和中心點x方向移動的距離 CGFloat yDistance; //觸摸點和中心點y方向移動的距離}@end
注意:
(1).CGPoint 只是typdef 過的一個struct結構體,是實值型別,千萬不能加星號(*)
struct CGPoint { CGFloat x; CGFloat y;};typedef struct CGPoint CGPoint;
(2).CGFloat實際上就是float
# define CGFLOAT_TYPE floattypedef CGFLOAT_TYPE CGFloat;
2.在MyButton.m中添加代碼
//手指按下開始觸摸- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{ //獲得觸摸在按鈕的父視圖中的座標 UITouch *touch = [touches anyObject]; CGPoint currentPoint = [touch locationInView:self.superview]; xDistance = self.center.x - currentPoint.x; yDistance = self.center.y - currentPoint.y; }//手指按住移動過程- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event{ if(isDrag) { //獲得觸摸在按鈕的父視圖中的座標 UITouch *touch = [touches anyObject]; CGPoint currentPoint = [touch locationInView:self.superview]; //移動按鈕到當前觸摸位置 CGPoint newCenter = CGPointMake(currentPoint.x + xDistance, currentPoint.y + yDistance); self.center = newCenter; } }
解釋:因為我們的MyButton繼承自UIButton,而UIButton繼承自UIControl,UIControl繼承自UIView,UIView繼承自UIResponder
UIResponder類提供了響應使用者互動的一些事件,以上兩個就在其中。這些函數都是系統回呼函數,也就是說當程式和使用者發生互動時,系統自動調用執行,無需程式員手動調用和響應。
最後只需在UIViewController中執行個體化MyButton,編譯運行就可以實現功能了。
註:從響應事件event中也能獲得所有觸摸的觸摸點集合:
NSSet *myTouches = [eventtouchesForView:self.view];
下面簡單介紹下IOS中的互動事件響應鏈:
響應者: |UIImageView
|UIApplication|UILabel
|UIButton
| ||UISlider
NSObject-----UIResponder------|UIView-------------------------|UIControl-----------------|
| ||UISwitch
|UIViewController|UIWindow
|UITextField
|UIScrollView
在IOS中當前接受觸摸的響應者對象被稱為第一響應者,即表示當前該對象正在與使用者互動,它是響應者鏈的開端。
響應者鏈表示一系列的響應者對象。事件被交由第一響應者對象處理,如果第一響應者不處理,事件被沿著響應者鏈向上傳遞,交給下一個響應者。一般來說,第一響應者是個視圖對象或者其子類對象,當其被觸摸後事件被交由它處理,如果它不處理,事件就會被傳遞給它的視圖控制器對象(如果存在),然後是它的父視圖(superview)對象(如果存在),以此類推,直到頂層視圖。接下來會沿著頂層視圖(top
view)到視窗(UIWindow對象)再到程式(UIApplication對象)。如果整個過程都沒有響應這個事件,該事件就被丟棄。一般情況下,在響應者鏈中只要由對象處理事件,事件就停止傳遞。但有時候可以在視圖的回應程式法中根據一些條件判斷來決定是否需要繼續傳遞事件。
視圖對觸摸事件是否需要作處回應可以通過設定視圖的userInteractionEnabled屬性。預設狀態為YES,如果設定為NO,可以阻止視圖接收和分發觸摸事件。
除此之外,當視圖被隱藏(setHidden:YES)或者透明(alpha值為0)也不會收事件。
不過這個屬性只對視圖有效,如果想要整個程式都步響應事件,可以調用UIApplication的beginIngnoringInteractionEvents方法來完全停止事件接收和分發。通過endIngnoringInteractionEvents方法來恢複讓程式接收和分發事件。
如果要讓視圖接收多點觸摸,需要設定它的multipleTouchEnabled屬性為YES,預設狀態下這個屬性值為NO,即視圖預設不接收多點觸摸。