在堆叠的UIWindows之间传递触摸?

时间:2013-02-06 23:33:30

标签: ios uiview touch uiwindow

我有两个窗户 - 一个是前窗,另一个是后窗。前面的一个用于覆盖后面的一些东西。我希望能够捕捉前窗某些部分的触摸,而不是其他部分;我希望前窗在某些区域接收触摸,但是将它们传递到其他区域的后窗。

关于我如何做到这一点的任何想法?

3 个答案:

答案 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]