2013-03-17 33 views
27

我有一個UIView('容器視圖'),其中包含幾個'子視圖'。我想在容器視圖中添加一個UITapGestureRecognizer,這樣當我觸摸容器視圖內的子區域之外的區域時,它將被激活。排除子視圖從UIGestureRecognizer

此刻,觸摸容器視圖中的任何位置,包括子視圖內激活手勢識別器。

實施看起來是這樣的: 在控制器:

ContainerView *containerView = [[ContainerView alloc] initWithSubViews:array]; 
UITapGestureRecognizer *tap = [UITapGestureRecognizer alloc] initWithTarget:self action:@selector(someSelector)]; 
[containerView addGestureRecognizer:tap]; 
[self.view addSubView:containerView]; 

在ContainerView.m

-(id)initWithSubviews:(NSArray *)array { 
    for (subView *s in array) { 
     [self addSubView:s]; 
    } 
    return self; 
} 

我覺得出現問題,因爲之後的子視圖是手勢識別添加。如果這是真的,那麼解決方案需要將initWithSubViews方法分成兩個獨立的方法,我寧願避免。

謝謝

回答

9

iOS 6中引入了一個偉大的新功能,解決了這個確切的問題 - 一個UIView(子視圖),可以從gestureRecognizerShouldBegin:返回NO(手勢識別器連接到超級觀點)。事實上,對於某些UIView子類而言,這已經是某些手勢識別器的默認設置(例如,UIButton關於連接到超級視圖的UITapGestureRecognizer)。

查看此主題的我的書:http://www.apeth.com/iOSBook/ch18.html#_gesture_recognizers

0

如果添加UITapGestureRecognizer爲ContainerView,它應該與各地ContainerView迴應。它不會介意它的子視圖。

檢查手勢位置,如果它位於您的子視圖位置,則跳過手勢操作。

- (void) tapGestureHandler:(UIGestureRecognizer *) gestureRecognizer { 


    CGPoint tapPoint = [gestureRecognizer locationInView:nil]; 

    //check your tapPoint contains ur subview frame, skip.else do ur actions 
} 
+0

如果需要檢查很多子視圖,這是昂貴和毛茸茸的。 – CodaFi 2013-03-17 03:51:37

+0

是。我看..我沒有看到任何其他好的解決方案..如果你有,請隨時分享.. :) – 2013-03-17 03:58:09

0

新增:

我只是想更好的東西。

在你的處理器

-(void)tapGestureHandler:(UITapGestureHandler)gesture 

檢查gesture.view是上海華。 如果點擊子視圖,它將返回子視圖。

============================================== ======

我會建議覆蓋內超監視。

​​

這就是所謂的以確定是否手勢落在視圖

看到了這個問題的答案,看看它的行爲默認內。

Event handling for iOS - how hitTest:withEvent: and pointInside:withEvent: are related?

你可以檢查點在任何子視圖。如果是,則返回零,否則返回自我。

OR

在每個子視圖的

,加tapgesture識別,什麼也不做。子視圖的手勢識別器將默認取消其超級視圖的手勢識別器。如果有很多子視圖,我會留意內存佔用情況。

+0

不幸的是,我認爲這不工作。根據文檔,gesture.view爲您提供了「手勢識別器所連接的視圖」。它給出了整個容器視圖而不是子視圖。 第二個選項看起來很有希望,我會放棄它。 – 2013-03-18 03:19:31

+0

太棒了,我通過使用hitTest:withEvent方法得到了它的工作。見下面的帖子。 – 2013-03-18 03:46:01

11

我設法得到它的工作通過執行以下操作:

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapGestureHandler:)]; 

// ... 

-(void) tapGestureHandler:(UITapGestureRecognizer *)sender { 
    CGPoint point = [sender locationInView:sender.view]; 
    UIView *viewTouched = [sender.view hitTest:point withEvent:nil]; 
    if ([viewTouched isKindOfClass:[ThingIDontWantTouched class]]) { 
     // Do nothing; 
    } else { 
     // respond to touch action 
    } 
} 
37

我用下面的簡單方法。 它工作得很周到!

實現UIGestureRecognizerDelegate功能,對上海華只接受沾上,而不是子視圖接受沾上:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 
{ 
    if (touch.view != _mySuperView) { // accept only touchs on superview, not accept touchs on subviews 
     return NO; 
    } 

    return YES; 
} 
4

記住添加和設置委託方法 -

在UIViewController的.h文件中包括這個代表

@interface YourViewController: UIViewController<UIGestureRecogniserDelegate> 

然後你在哪裏創建喲烏爾tapGesture對象,(內viewDidLoad中例如)

UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc]initWithTarget:self action:@selector(actionMethodYouWantToHappenOnTap)]; 

    tap.delegate = self; //Remember to set delegate! Otherwise the delegate method won't get called. 

    [self.view addGestureRecognizer:tap]; 

記住設置委託方法tap.delegate = self;然後抽頭委託方法現在將火上抽頭。

在這個方法中,你處理的時候你想點擊手勢識別時所使用,在我的代碼我希望它忽略了一個水龍頭如果一個特定的子視圖是可見

-(BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer{ 

    if (!mySubview.hidden){ 
    return NO; //This fired if said subview was visible, though whatever the condition of where and when you want tap to work, can be handled within this delegate method. 
    } 

    return YES; 
} 

我希望這可以幫助別人有同樣的問題。記住設置我發現的委託方法是很容易被忽略的。

乾杯

2

很多答案,增加了另一種替代解決方案。初始化子視圖的視圖標記你不希望從爲1個接收觸摸並執行以下操作:

- (void)viewDidLoad { 
    [super viewDidLoad]; 
    UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleTap:)]; 
    tap.delegate = self; 
    [self.view addGestureRecognizer:tap]; 
} 

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch 
{ 
    if (touch.view.tag == 1) { 
     return NO; 
    } 
    return YES; 
} 

-(void)handleTap:(id)sender 
{ 
//Handle tap... 
} 

這種方式,觸摸手勢只會從你需要它的意見接收。