SwiftUI:如何使用非模拟器支持的框架和 PreviewProvider?
SwiftUI: How to work with non-simulator supported frameworks and PreviewProvider?
我正在开发 RealityKit 应用程序,并使用 SwiftUI。
当然,RealityKit 视图在 SwiftUI PreviewProvider
预览中不起作用。但我的问题是,即使是简单且完全隔离的 SwiftUI 视图也无法预览,因为 PreviewProvider
需要编译整个项目。
我的 SwiftUI 视图 类 没有以任何方式连接到 ARView 代码。如果我只是去 "File" -> "New" 并选择一个 SwiftUI 文件,然后尝试在 canvas (⌥ + ⌘ + ↵) 中预览它就足够了,没有任何更改。然后它会给我那个错误。我的 .xcodeproj
中有任何代码不受 canvas 预览支持,这一事实会产生错误。
我收到这样的错误:
Value of type 'ARView' has no member 'installGestures'
我现在仅有的两个解决方案是 1) 将文件复制到 Playground 并在那里进行试验,然后在完成后复制回来。 2) 在处理视图之前,注释掉所有不受支持的 RealityKit 相关代码。
问:当然,这些解决方案都不是最优的。还有更好的解决方案吗?
虽然 iOS13 中的新模拟器支持 Metal,但 ARView 需要实际设备来捕获相机帧并生成传感器融合数据。它有大量的属性和方法,您需要模拟这些属性和方法以允许与其他代码交互。
你能否通过另一个 class 实现的协议抽象出 SwiftUI 之间的 ARView 交互,例如 UIView 或 UIViewController subclass?如果协议足够简单,您可以创建一个可以模拟交互的 class - 响应您的 SwiftUI 视图,就好像它实际上是在与 ARView 通信一样,而不需要实现整个 ARView API。
您的 SwiftUI 视图可能不应该直接处理设置和对 ARView 的属性和方法的任意访问。您可以围绕 ARView 创建一个包装器,并通过组合发布者和订阅者呈现应用程序级别的逻辑和操作。包装 UIView 并具有相同 pub/subs 的模拟版本可以呈现简单的视觉提示,例如更改颜色,以表示 ARView 的不同状态等。
我遇到了同样的问题。我的解决方案是像这样使用 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
我正在开发 RealityKit 应用程序,并使用 SwiftUI。
当然,RealityKit 视图在 SwiftUI PreviewProvider
预览中不起作用。但我的问题是,即使是简单且完全隔离的 SwiftUI 视图也无法预览,因为 PreviewProvider
需要编译整个项目。
我的 SwiftUI 视图 类 没有以任何方式连接到 ARView 代码。如果我只是去 "File" -> "New" 并选择一个 SwiftUI 文件,然后尝试在 canvas (⌥ + ⌘ + ↵) 中预览它就足够了,没有任何更改。然后它会给我那个错误。我的 .xcodeproj
中有任何代码不受 canvas 预览支持,这一事实会产生错误。
我收到这样的错误:
Value of type 'ARView' has no member 'installGestures'
我现在仅有的两个解决方案是 1) 将文件复制到 Playground 并在那里进行试验,然后在完成后复制回来。 2) 在处理视图之前,注释掉所有不受支持的 RealityKit 相关代码。
问:当然,这些解决方案都不是最优的。还有更好的解决方案吗?
虽然 iOS13 中的新模拟器支持 Metal,但 ARView 需要实际设备来捕获相机帧并生成传感器融合数据。它有大量的属性和方法,您需要模拟这些属性和方法以允许与其他代码交互。
你能否通过另一个 class 实现的协议抽象出 SwiftUI 之间的 ARView 交互,例如 UIView 或 UIViewController subclass?如果协议足够简单,您可以创建一个可以模拟交互的 class - 响应您的 SwiftUI 视图,就好像它实际上是在与 ARView 通信一样,而不需要实现整个 ARView API。
您的 SwiftUI 视图可能不应该直接处理设置和对 ARView 的属性和方法的任意访问。您可以围绕 ARView 创建一个包装器,并通过组合发布者和订阅者呈现应用程序级别的逻辑和操作。包装 UIView 并具有相同 pub/subs 的模拟版本可以呈现简单的视觉提示,例如更改颜色,以表示 ARView 的不同状态等。
我遇到了同样的问题。我的解决方案是像这样使用 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