2010-09-30 62 views
75

我有覆蓋在許多其他視圖之上的視圖。我只使用這個方法來檢測屏幕上的某些觸摸,但除此之外,我不希望視圖停止其他視圖的行爲,這些視圖是滾動視圖等。如何將所有觸摸轉發這個覆蓋視圖?它是UIView的一個subcalss。iOS - 通過視圖轉發所有觸摸

回答

0

嘗試這樣的事情......

for (UIView *view in subviews) 
    [view touchesBegan:touches withEvent:event]; 

上面的代碼中,例如您的touchesBegan方法會通過觸摸到所有的觀點的子視圖。

+6

這種方法AFAIK的問題是,試圖觸摸轉發給UIKit框架中的類將最經常沒有影響。根據Apple的文檔,UIKit框架類不能用於接收將視圖屬性設置爲其他視圖的觸摸。所以這種方法主要用於UIView的自定義子類。 – maciejs 2011-03-02 23:05:35

4

如果你要轉發的觸摸視圖,以不正好是一個子視圖/上海華盈,你可以設置自定義屬性在你的UIView子類,像這樣:

@interface SomeViewSubclass : UIView { 

    id forwardableTouchee; 

} 
@property (retain) id forwardableTouchee; 

確保合成它在您的m:

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 

    [self.forwardableTouchee touchesBegan:touches withEvent:event]; 

} 

@synthesize forwardableTouchee; 

,然後再向您的任何UIResponder方法,如下面的

無論你實例化你的UIView,設置forwardableTouchee屬性無論大家認爲你想將事件轉發到:

SomeViewSubclass *view = [[[SomeViewSubclass alloc] initWithFrame:someRect] autorelease]; 
    view.forwardableTouchee = someOtherView; 
75

對於從覆蓋視圖傳遞觸摸到的意見下,實現以下方法了UIView:

目的-C:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event { 
    NSLog(@"Passing all touches to the next view (if any), in the view stack."); 
    return NO; 
} 

夫特:

override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 
    print("Passing all touches to the next view (if any), in the view stack.") 
    return false 
} 
+2

我有同樣的問題,但我想要的是,如果我用手勢縮放/旋轉/移動視圖,那麼它應該返回yes,對於休息事件,它應該返回no,我該如何實現? – Minakshi 2013-08-12 06:27:33

58
myWebView.userInteractionEnabled = NO; 

是我所需要的!

38

這是一箇舊線程,但它出現在搜索中,所以我想我會添加我的2c。我有一個子視圖覆蓋的UIView,只希望攔截擊中子視圖之一的觸摸,所以我修改PixelCloudSt的回答

-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    for (UIView* subview in self.subviews) { 
     if ([subview hitTest:[self convertPoint:point toView:subview] withEvent:event] != nil) { 
      return YES; 
     } 
    } 
    return NO; 
} 
+1

您需要創建一個自定義的UIView子類(或任何其他UIView子類的子類,例如UIImageView或其他)並覆蓋此函數。本質上,子類在.h文件中可以有一個完全空的'@interface',上面的函數是'@implementation'的全部內容。 – fresidue 2014-03-07 16:01:14

-1

正如@PixelCloudStv如果你想扔感動從一個視圖建議另一個但在這個過程中一些額外的控制 - 子類的UIView

//頭

@interface TouchView : UIView 

@property (assign, nonatomic) CGRect activeRect; 

@end 

//執行

#import "TouchView.h" 

@implementation TouchView 

#pragma mark - Ovverride 

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    BOOL moveTouch = YES; 
    if (CGRectContainsPoint(self.activeRect, point)) { 
     moveTouch = NO; 
    } 
    return moveTouch; 
} 

@end 

在interfaceBuilder中,只需將View的類設置爲TouchView並將rect設置爲活動矩形。你也可以改變和實現其他邏輯。

3

我有一個與UIStackView類似的問題(但可以是任何其他視圖)。 我的配置是如下: View controller with containerView and StackView

這就是我有一個需要被放置在後臺,與上側的按鈕的容器中的情況下,經典。爲了佈局的目的,我在UIStackView中包含了這些按鈕,但是現在stackView的中間(空)部分攔截了觸摸:-(

我所做的是創建一個UIStackView的子類,該子類定義了應該是子視圖的屬性可觸摸 現在,任何觸摸按鈕(包含在* viewsWithActiveTouch *數組中)將被賦予按鈕,而任何觸摸堆棧視圖的任何地方都不會被截取,因此傳遞給任何下面的堆棧視圖。

/** Subclass of UIStackView that does not accept touches, except for specific subviews given in the viewsWithActiveTouch array */ 
class NoTouchStackView: UIStackView { 

    var viewsWithActiveTouch: [UIView]? 

    override func hitTest(point: CGPoint, withEvent event: UIEvent?) -> UIView? { 

    if let activeViews = viewsWithActiveTouch { 
     for view in activeViews { 
      if CGRectContainsPoint(view.frame, point) { 
       return view 

      } 
     } 
    } 
    return nil 
    } 
} 
14

改進版@fresidue答案。您可以使用此UIView子類作爲透明視圖通過觸摸歐在其子視圖旁邊。實施Objective-C的

@interface PassthroughView : UIView 

@end 

@implementation PassthroughView 

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event 
{ 
    for (UIView *view in self.subviews) { 
     if (!view.hidden && [view pointInside:[self convertPoint:point toView:view] withEvent:event]) { 
      return YES; 
     } 
    } 
    return NO; 
} 

@end 

斯威夫特:

class PassthroughView: UIView { 
    override func point(inside point: CGPoint, with event: UIEvent?) -> Bool { 
    return subviews.contains(where: { 
     !$0.isHidden && $0.point(inside: self.convert(point, to: $0), with: event) 
    }) 
    } 
}