【问题标题】:SwiftUI: How to work with non-simulator supported frameworks and PreviewProvider?SwiftUI:如何使用非模拟器支持的框架和 PreviewProvider?
【发布时间】:2019-12-26 21:09:23
【问题描述】:

我正在开发 RealityKit 应用,并使用 SwiftUI。

当然,RealityKit 视图在 SwiftUI PreviewProvider 预览中不起作用。但我的问题是,即使是简单且完全隔离的 SwiftUI 视图也无法预览,因为 PreviewProvider 需要编译整个项目。

我的 SwiftUI View 类没有以任何方式连接到 ARView 代码。如果我只是去“文件”->“新建”并选择一个 SwiftUI 文件,然后尝试在画布中预览它(⌥ + ⌘ + ↵)就足够了,没有任何更改。然后它会给我那个错误。只是在我的.xcodeproj 中有任何不受画布预览支持的代码的事实,都会产生错误。

我收到这样的错误:

Value of type 'ARView' has no member 'installGestures'

我目前仅有的两个解决方案是 1) 将文件复制到 Playground 并在那里进行试验,然后在完成后复制回来。 2) 在处理视图之前,注释掉所有不受支持的 RealityKit 相关代码。

Q:当然,这些解决方案都不是最优的。有没有更好的解决方案?

【问题讨论】:

  • 在这里搜索 [xcode] swift 条件构建。我收到了 26 个点击,其中包括:stackoverflow.com/questions/55133043/… 现在,如果这些结果没有帮助,删除“swift”会将结果扩展到 188。您的答案确实是使用 Xcode 进行条件构建。但最简单的方法是什么?使用运行 iOS 13 的设备。我知道,这可能不可行,但您至少会感觉到实时性能和其他您可能没有想到的问题。
  • Beta6 中也会出现这种情况吗?我在某处读到它应该是一个错误。
  • @Fabian 是的,它也发生在最新的测试版上。你还记得你在哪里读到的吗? Twitter 还是博客?
  • 遗憾的是现在没有了,我希望他们尽可能修复它
  • 希望如此。这似乎是一个错误,因为能够预览一个孤立的 SwiftUI 视图文件似乎是合理的,而不依赖于我的 .xcodeproj 中的所有其他不相关文件。

标签: swift swiftui arkit realitykit


【解决方案1】:

虽然 iOS 13 中的新模拟器支持 Metal,但 ARView 需要实际设备来捕获相机帧并生成传感器融合数据。它有大量的属性和方法,您需要模拟它们以允许与其他代码进行交互。

你能否通过另一个类实现的协议抽象出 SwiftUI 之间的 ARView 交互,例如 UIView 或 UIViewController 子类?如果协议足够简单,您可以创建一个可以模拟交互的类 - 响应您的 SwiftUI 视图,就好像它实际上是在与 ARView 通信一样,而无需实现整个 ARView API。

您的 SwiftUI 视图可能不应该直接处理对 ARView 的属性和方法的设置和任意访问。您可以围绕 ARView 创建一个包装器,并通过组合发布者和订阅者呈现应用程序级别的逻辑和操作。它的模拟版本包装了 UIView 并具有相同的 pub/subs 可以呈现简单的视觉提示,例如更改颜色,以表示 ARView 的不同状态等。

【讨论】:

  • 我的 SwiftUI View 类没有以任何方式连接到 ARView 代码。如果我只是去“文件”->“新建”并选择一个 SwiftUI 文件,然后尝试在画布中预览它(⌥ + ⌘ + ↵)就足够了,没有任何更改。然后它会给我那个错误。只是在我的.xcodeproj 中有任何不受画布预览支持的代码的事实,都会产生错误。
【解决方案2】:

我遇到了同样的问题。我的解决方案是像这样使用 targetEnvironment(simulator) 编译器指令:

struct ContentView : View {
    
    var body: some View {
            #if !targetEnvironment(simulator)
            ARViewContainer()
                .edgesIgnoringSafeArea(.all)
                .statusBar(hidden: true)
            #endif
        }
    }
}

#if !targetEnvironment(simulator)
struct ARViewContainer: UIViewRepresentable {
    
    func makeUIView(context: Context) -> ARView {
        let arView = ARView(frame: .zero)

        // ARKit / RealityKit specific code
        ...

        return arView
        
    }
    
    func updateUIView(_ arView: ARView, context: Context) {}
}
#endif

延伸阅读:https://www.hackingwithswift.com/example-code/language/how-to-use-compiler-directives-to-detect-the-ios-simulator

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-03
    • 2021-04-19
    • 1970-01-01
    • 1970-01-01
    • 2013-12-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多