如何用UIGestureRecognizer去偵測使用者輸入

在3.2以前,我們要拿到UITouch跟使用者互動,大部分都是透過UIResponder的四種methods

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

有些人會把UITouch重新wrap丟到自己的queue裏面去處理,

不然就是直接在這幾個function裏直接判斷,其實都不會差太多,簡單的說...就是麻煩 

3.2以後,透過UIGestureRecognizer及其它繼承它的UIxxxGestureRecognizer,

偵測使用者輸入就變的簡單許多

UILongPressGestureRecognizer
UIPanGestureRecognizer
UIPinchGestureRecognizer
UIRotationGestureRecognizer
UISwipeGestureRecognizer
UITapGestureRecognizer

照名字看大概就知道這是做什麼用的,所以我就不解釋啦,直接看用法.....

以UIPanGestureRecognizer爲例,這是處理使用者用一隻手指(或多隻)在屏幕上滑來滑去的動作,

要偵測這個動作,只要加下面這段code進viewDidLoad或任何你需要的地方...

UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanFrom:)];
[self.view addGestureRecognizer:panRecognizer];
panRecognizer.maximumNumberOfTouches = 1;
panRecognizer.delegate = self;
[panRecognizer release];

第一個很簡單,就是確定要給這個recognizer handle的event,就會去call這個class底下的handlePanFrom:

然後把recognizer加進UIView裏(addGestureRecognizer),

因爲同時間我只想知道一隻手指的動作,所以我用maximumNumberOfTouches=1來限制,

當然,你可以改變maximumNumberOfTouches跟minimumNumberOfTouches的值來當成filter,接着把delegate設定成自己(記得header要加上UIGestureRecognizerDelegate),不過這樣還沒有結束...

我們要補上這個delegate method

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
}

裏面可以先filter event,決定要不要丟給一開始assign給panRecognizer的selector function

譬如我只想要看某個subview的事件

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch{
   UIView *aview = [self.view viewWithTag:1000];
   if (touch.view != aview) {
     return NO; // 不理這個event
   }
   return YES;
}

接下來就是

- (void)handlePanFrom:(UIPanGestureRecognizer *)recognizer {        
        //拿到手指目前的位置
        CGPoint location = [recognizer locationInView:self.view];
        UIView *aview = [self.view viewWithTag:1000];

        // 如果UIGestureRecognizerStateEnded的話...你是拿不到location的
        // 不判斷的話,底下改frame會讓這個subview消失,因為origin的x和y就不見了!!!
        if(recognizer.state != UIGestureRecognizerStateEnded)
        {
                aview.frame = CGRectMake(location.x, location.y, aview.frame.size.width, aview.frame.size.height);
        }
}

不同的UIGestureRecognizer subclass都會有不同特點,譬如說Pinch的scale,velocity和Swipe的direction,

直接簡化了處理UITouch的步驟,大家只要知道這些特點,處理使用者輸入就會得心應手啦~

遇到靈異事件...記得先看看有沒有判斷UIGestureRecognizer的state



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章