SwiftUI 将触摸事件从 UIViewControllerRepresentable 传递到后面的 View

Nic*_*ell 6 touch uikit ios swift swiftui

我正在开发一个混合使用 UIKit 和 SwiftUI 的项目。我目前有一个 ZStack,我将我的 SwiftUI 内容保存在其中,我需要在该内容之上显示一个 UIViewController。所以我的 ZStack 中的最后一项是 UIViewControllerRepresentable。IE:

ZStack {
   ...
   SwiftUIContent
   ...
   MyUIViewControllerRepresentative() 
}

Run Code Online (Sandbox Code Playgroud)

我覆盖的 UIViewControllerRepresentative 是其他 UIViewControllers 的容器。那些子视图控制器并不总是需要占据全屏,因此 UIViewControllerRepresentative 具有透明背景,因此用户可以与后面的 SwiftUI 内容进行交互。

我面临的问题是 UIViewControllerRepresentative 阻止所有触摸事件到达 SwiftUI 内容。

我试过像这样覆盖 UIViewControllers 视图命中测试:

override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    // return nil if the touch event should propagate to the SwiftUI content
}
Run Code Online (Sandbox Code Playgroud)

我还尝试通过以下方式完全删除视图控制器视图上的触摸事件:

view.isUserInteractionEnabled = false
Run Code Online (Sandbox Code Playgroud)

即使那样也行不通。

任何帮助将非常感激。

小智 8

解决方案:

我设法想出了一个可行的解决方案。

我没有将 UIViewControllerRepresentable 放入 ZStack 中,而是创建了一个自定义 ViewModifier,它将内容值传递到 UIViewControllerRepresentable 中。然后,通过将内容包装在 UIHostingController 内并将其添加为子视图控制器,将该内容嵌入到我的 UIViewController 中。

ZStack {
    ... SwiftUI content ...
}.modifier(MyUIViewControllerRepresentative)
Run Code Online (Sandbox Code Playgroud)

  • 全面实施将会很有趣。尽管我原则上理解所提出的解决方案,但我很难弄清楚细节,例如“innerSwiftUIContent”应该是什么类型?如果您可以编辑您的答案以添加更多详细信息,它可能会更有帮助和感激! (3认同)

小智 5

您可以在 UIViewControllerRepresentable 上使用 allowedHitTesting() 修饰符。

正如 Paul Hudson 在他的网站上所说: https: //www.hackingwithswift.com/quick-start/swiftui/how-to-disable-taps-for-a-view-using-allowshittesting

“如果视图不允许进行命中测试,则任何点击都会自动继续通过视图到达后面的任何内容。”

ZStack {
   ...
   SwiftUIContent
   ...
   MyUIViewControllerRepresentative()
       .allowsHitTesting(false)
}
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,这*不一定*有效。我有一个 SwiftUI 视图,位于通过“SpriteView”呈现的 SpriteKit“SKScene”之上。即使使用“allowsHitTesting(false)”和“disabled(true)”,顶部的 SwiftUI 视图也会拦截触摸。 (2认同)