2011年4月28日 星期四

如何讓手勢偵測在subview裡作用? (How to make UIGestureRecognizer work in subview?)

我們都知道UIGestureRecognizer只支援iOS3.2以上的環境
但是讀過Jesse的文章之後,我覺得我可以很放心的去使用這個API

網路上也很多這類的文章,詳細的原理可以參考官方文件
我僅針對我實作過程中所遇到的問題 貼上一些個人的解法跟筆記
在一陣copy paste過後,程式編譯似乎沒什麼問題,可是就是手勢沒反應

1
[self.imageView addGestureRecognizer:tapGestureRecognize];

因為人家的事件是發生在UIView上面…不是UIimageView

2. 那不指定self.view可以換成別的subview嗎?
當然可以阿,在接收到gesture時filter掉我們不接受的view或是特定範圍,
使用下面這個event function

1
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch

3. 喂~沒反應阿! gestureRecognizer: shouldReceiveTouch: 根本就沒有觸發進來阿
喔~我想您跟我的煩惱是一樣滴,因為沒花一些時間k文件才會出現觀念上的問題
UIGestureRecogizer根本就沒有委託來處理這樣的event,當然會遲遲等不到event的發生阿
所以呢?

所以開始貼一些code吧
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
//.h
@interface showDigitNumberController : UIViewController


//.m
// Create the Swipe Gesture Recognizer
UISwipeGestureRecognizer *SwipeRecognizer = nil;
 
SwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
                                                            action:@selector(mySwipeGestureRecognizer:)];
[SwipeRecognizer setDirection:(UISwipeGestureRecognizerDirectionUp)];
[self.view addGestureRecognizer:SwipeRecognizer];
// assign the delegate here
SwipeRecognizer.delegate = self;
[SwipeRecognizer release];
 
SwipeRecognizer = [[UISwipeGestureRecognizer alloc] initWithTarget:self
                                                            action:@selector(mySwipeGestureRecognizer:)];
[SwipeRecognizer setDirection:(UISwipeGestureRecognizerDirectionDown)];
[self.view addGestureRecognizer:SwipeRecognizer];
[SwipeRecognizer release];
 
// Create Single Tap Gesture Recognizer
UITapGestureRecognizer *tapGestureRecognize = [[UITapGestureRecognizer alloc] initWithTarget:self
      action:@selector(myTapGestureRecognizer:)];
tapGestureRecognize.numberOfTapsRequired = 1;
[self.view addGestureRecognizer:tapGestureRecognize];
[tapGestureRecognize release];

- (void)mySwipeGestureRecognizer:(UISwipeGestureRecognizer *)Sender {
 switch(Sender.direction){
   case UISwipeGestureRecognizerDirectionUp:
  // do something 
        break;
   case UISwipeGestureRecognizerDirectionDown:
  // do something 
        break;
   case UISwipeGestureRecognizerDirectionLeft:
  // do something 
        break;
   case UISwipeGestureRecognizerDirectionRight:
  // do something 
        break;
   default:
        break;
 }
}

- (void)myTapGestureRecognizer:(UITapGestureRecognizer *)Sender{
 // do something
}

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


4. 誠如先前所講的,若是要讓指定的subview接受gesture的event就是在這個function裡實作
   網路上所提到的作法也是百百種

   //有將superview給filter掉的作法
   //UIView *gview; //This is the superview containing the buttons
   //if([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]])
   //     return !([touch.view isKindOfClass:[UIButton class]] && [touch.view
   //isDescendentOfView:gview]);


   //也有使用touch.view == menu1Btn || touch.view == menu2Btn …龐大if判斷式的作法
   //http://stackoverflow.com/questions/4556944/a-tips-for-testing-existence-of-subviews


    //就連官方sample code的作法也是if判斷的作法
    //if ((touch.view == segmentedControl) && (gestureRecognizer == tapRecognizer)) {
    //    return NO;
    //}
    //return YES;

    我的作法也是把不想接受到的gesture event的物件給填進去,不過沒有預期的效果
    那到底怎麼偵測一個subview的手勢呢?
    a. 首先我在xib裡面view底下又多加了一個UIView, 並且指定我要的範圍大小
    b. 在.h及.m裡將這個UIView的getter setter設定好,並確定xib的link有拉好
    c. 在原先指定addGestureRecognizer的view換成custom的這個就好了耶

內容回應