如何忽略触摸事件并将它们传递给另一个子视图的UIControl对象?
我有一个自定义的UIViewController其UIView占据了屏幕的一angular,但其中大部分是透明的,除了它的一些button和东西的部分。 由于该视图上的对象的布局,视图的框架可以掩盖它下面的一些button。 我希望能够忽略对这个视图的任何接触,如果他们没有触及任何重要的东西,但我似乎只能够传递实际的触摸事件(touchesEnded / nextResponder的东西)。 如果我有一个UIButton或类似的东西不使用touchesEnded,我怎样才能通过触摸事件呢?
我不能手动弄清楚buttonselect器的调用,因为这个自定义的ViewController可以用在许多不同的视图上。 我基本上需要一种方法来调用这个:
[self.nextResponder touchesEnded:touches withEvent:event];
在UIControltypes以及。
可能最好的方法是重写hitTest:withEvent:
在视图中,你想忽略触摸。 根据您的视图层次结构的复杂性,有几个简单的方法来做到这一点。
如果您有对视图下方的视图的引用来忽略:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView *hitView = [super hitTest:point withEvent:event]; // If the hitView is THIS view, return the view that you want to receive the touch instead: if (hitView == self) { return otherView; } // Else return the hitView (as it could be one of this view's buttons): return hitView; }
如果您没有对视图的引用:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event { UIView *hitView = [super hitTest:point withEvent:event]; // If the hitView is THIS view, return nil and allow hitTest:withEvent: to // continue traversing the hierarchy to find the underlying view. if (hitView == self) { return nil; } // Else return the hitView (as it could be one of this view's buttons): return hitView; }
我会build议第一种方法是最强大的(如果可以获得对底层视图的引用)。
我还没有find在对象之间传递UITouch事件的好方法。 通常更好的方法是实现hitTest并返回nil,如果该点不在要处理的视图中:
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
迅速回答:
你可以创build一个UIView子类,IgnoreTouchView。 在故事板中,将其设置在您要通过触摸传递的VC视图上:
class IgnoreTouchView : UIView { override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? { let hitView = super.hitTest(point, with: event) if hitView == self { return nil } return hitView } }
请注意,您必须将UserInteractionEnabled设置为true,对于所讨论的UIView!
这是一个古老的问题,它出现在search的顶部。 所以,我想我会张贴另一个可能的解决scheme,可能会更好地为您的情况。 在我的情况下,我想拖一个标签在另一个标签的顶部,我想在hitTest中获得下面的标签。 最简单的做法是将userInteractionEnabled
设置为NO
或false
,然后执行hitTest,如果需要再次移动,请将其重新设置。 以下是Swift中的代码示例:
override func touchesEnded(touches: Set<UITouch>, withEvent event: UIEvent?) { let touch = touches.first let location = touch?.locationInView(self.view) self.label1.userInteractionEnabled = false let view = self.view.hitTest(location!, withEvent: nil) as? UILabel print(view?.text) self.label1.userInteractionEnabled = true }
我的问题是类似的:我有一个UIControl与复杂的触摸响应,但它embedded在滚动视图时很有趣…
当子视图具有活动的触摸手势时,这防止了父滚动(或者可以被修改以防止其他交互)。
我的解决scheme
在子视图中为didBeginInteraction和didEndInteraction创build一个委托协议。
从touchesBegan调用delegate.didBeginInteraction
从touchesEnded调用delegate.didEndInteraction并触发Cancelled
在父控制器中,实现didBegin和didEnd协议,设置委托
然后在didBegin中设置scrollView.scrollEnabled = NO,在didEnd中设置scrollEnabled = YES。
希望这可以帮助一个与使用情况略有不同的人提出的问题!