sol*_*sol 125 events touch uiview
我有一个视图叠加在许多其他视图之上.我只是使用过度的方法来检测屏幕上的一些触摸,但除此之外我不希望视图停止下面其他视图的行为,这些是滚动视图等.我怎样才能转发所有的触摸通过这个叠加视图?它是UIView的子项.
Pix*_*dSt 105
要将覆盖视图中的触摸传递到下面的视图,请在UIView中实现以下方法:
Objective-C的:
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {
NSLog(@"Passing all touches to the next view (if any), in the view stack.");
return NO;
}
Run Code Online (Sandbox Code Playgroud)
迅速:
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
}
Run Code Online (Sandbox Code Playgroud)
rmp*_*251 105
myWebView.userInteractionEnabled = NO;
Run Code Online (Sandbox Code Playgroud)
就是我所需要的一切!
fre*_*due 52
这是一个旧线程,但它出现在搜索上,所以我想我会添加我的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;
}
Run Code Online (Sandbox Code Playgroud)
Tim*_*ich 34
@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
Run Code Online (Sandbox Code Playgroud)
在斯威夫特:
class PassthroughView: UIView {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
return subviews.contains(where: {
!$0.isHidden
&& $0.isUserInteractionEnabled
&& $0.point(inside: self.convert(point, to: $0), with: event)
})
}
}
Run Code Online (Sandbox Code Playgroud)
小智 10
我需要通过 UIStackView 传递触摸。内部的 UIView 是透明的,但 UIStackView 消耗了所有触摸。这对我有用:
class PassThrouStackView: UIStackView {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let view = super.hitTest(point, with: event)
if view == self {
return nil
}
return view
}
}
Run Code Online (Sandbox Code Playgroud)
所有排列的子视图仍然接收触摸,但对 UIStackView 本身的触摸会传递到下面的视图(对我来说是一个 mapView)。
如果要转发的视图不是子视图/超级视图,则可以在UIView子类中设置自定义属性,如下所示:
@interface SomeViewSubclass : UIView {
id forwardableTouchee;
}
@property (retain) id forwardableTouchee;
Run Code Online (Sandbox Code Playgroud)
确保在你的.m中合成它:
@synthesize forwardableTouchee;
Run Code Online (Sandbox Code Playgroud)
然后在您的任何UIResponder方法中包含以下内容,例如:
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
[self.forwardableTouchee touchesBegan:touches withEvent:event];
}
Run Code Online (Sandbox Code Playgroud)
无论您在何处实例化UIView,都要将forwardableTouchee属性设置为您要将事件转发到的任何视图:
SomeViewSubclass *view = [[[SomeViewSubclass alloc] initWithFrame:someRect] autorelease];
view.forwardableTouchee = someOtherView;
Run Code Online (Sandbox Code Playgroud)
我有一个与UIStackView类似的问题(但可能是任何其他视图).我的配置如下:
这是一个经典案例,我有一个需要放在背景中的容器,侧面有按钮.出于布局目的,我在UIStackView中包含了按钮,但现在stackView的中间(空)部分拦截了触摸:-(
我所做的是创建一个UIStackView的子类,其中一个属性定义了应该可触摸的subView.现在,对侧按钮(包含在*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
}
}
Run Code Online (Sandbox Code Playgroud)
在斯威夫特 5
class ThroughView: UIView {
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
guard let slideView = subviews.first else {
return false
}
return slideView.hitTest(convert(point, to: slideView), with: event) != nil
}
}
Run Code Online (Sandbox Code Playgroud)
看起来即使你这里有很多答案,但没有一个是我需要的快速干净的。所以我在这里接受了 @fresidue 的回答,并将其转换为 swift,因为它是现在大多数开发人员想要在这里使用的。
它解决了我的问题,我有一些带有按钮的透明工具栏,但我希望工具栏对用户不可见,并且触摸事件应该通过。
根据我的测试,isUserInteractionEnabled = false 正如某些人所述不是一个选项。
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
for subview in subviews {
if subview.hitTest(convert(point, to: subview), with: event) != nil {
return true
}
}
return false
}
Run Code Online (Sandbox Code Playgroud)
尝试这样的事情......
for (UIView *view in subviews)
[view touchesBegan:touches withEvent:event];
Run Code Online (Sandbox Code Playgroud)
例如,上面的代码在您的 TouchesBegan 方法中会将触摸传递给视图的所有子视图。
归档时间: |
|
查看次数: |
62666 次 |
最近记录: |