我有两个窗户 - 一个是前窗,另一个是后窗。前面的一个用于覆盖后面的一些东西。我希望能够捕捉前窗某些部分的触摸,而不是其他部分;我希望前窗在某些区域接收触摸,但是将它们传递到其他区域的后窗。
关于我如何做到这一点的任何想法?
答案 0 :(得分:33)
好的,这就是我所做的:我在前窗口创建了两个视图。第一个视图涵盖了我想要触及的区域;第二,我希望触摸通过。我对UIWindow进行了分类并覆盖了hitTest:withEvent方法,如下所示:
- (UIView *) hitTest:(CGPoint)point withEvent:(UIEvent *)event {
// See if the hit is anywhere in our view hierarchy
UIView *hitTestResult = [super hitTest:point withEvent:event];
// ABKSlideupHostOverlay view covers the pass-through touch area. It's recognized
// by class, here, because the window doesn't have a pointer to the actual view object.
if ([hitTestResult isKindOfClass:[ABKSlideupHostOverlayView class]]) {
// Returning nil means this window's hierachy doesn't handle this event. Consequently,
// the event will be passed to the host window.
return nil;
}
return hitTestResult;
}
在创建前窗的类中,我使用手势识别器来捕捉第一个视图的触摸。
2017年代码相同:
class PassView: UIView {}
class UIHigherWindow: UIWindow {
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
if hitView!.isKind(of: PassView.self) {
return nil
}
return hitView
}
}
你的“超级”窗口将是一些视图控制器,UberVc。
让UberVc的主视图(也就是简单的背景.view)成为PassView。
然后在UberVc上添加说按钮等。
以上代码会导致任何点击UberVc的按钮,以及任何不在按钮上的点击(即“背景”上的点击)都会进入常规窗口/ VC。
答案 1 :(得分:0)
我遇到了类似的问题:附加的UIWindow应该有一个透明视图,并带有一些难以处理的子视图。必须通过那些难以处理的视图之外的所有接触。
我最终使用了使用视图标记而不是类型检查的Anna代码的修改版本。这种方式不需要创建子类创建:
class PassTroughWindow: UIWindow {
var passTroughTag: Int?
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
let hitView = super.hitTest(point, with: event)
if let passTroughTag = passTroughTag {
if passTroughTag == hitView?.tag {
return nil
}
}
return hitView
}
}
假设您创建了一个窗口和根视图控制器,您可以像这样使用它:
let window: PassTroughWindow
//Create or obtain window
let passTroughTag = 42
window.rootViewController.view.tag = passTroughTag
window.passTroughTag = passTroughTag
//Or with a view:
let untouchableView: UIView // Create it
untouchableView.tag = passTroughTag
window.addSubview(untouchableView)
答案 2 :(得分:-4)
使用[[UIApplication sharedApplication] keyWindow]
获取关键窗口,然后将视图添加到其中,而不是使用多个UIWindows:
mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview:view]