32

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

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

4

3 回答 3

43

好的,这就是我所做的:我在前窗口中创建了两个视图。第一个视图覆盖了我想要捕捉的区域;第二个,我希望触摸通过的地方。我将 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
    }
}

您的“uber”窗口将是一些视图控制器,UberVc。

只需将UberVc的主视图(即简单的背景.view)设为PassView即可。

然后在 UberVc 上添加说按钮等。

上面的代码会导致对按钮的任何点击进入 UberVc,而对按钮以外的任何点击(即在“背景”上)都会进入您的常规窗口/VC。

于 2013-05-08T23:29:52.970 回答
2

我有一个类似的问题:额外的 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)
于 2017-12-25T19:49:48.887 回答
-4

不要使用多个 UIWindows,而是使用 获取关键窗口[[UIApplication sharedApplication] keyWindow],然后将视图添加到其中:

mainWindow = [[UIApplication sharedApplication] keyWindow];
[mainWindow addSubview:view]
于 2013-06-23T16:01:52.753 回答