SwiftUI:如何使用不受模拟器支持的框架和PreviewProvider?

时间:2019-08-21 14:43:58

标签: swift arkit swiftui

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

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

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

我收到这样的错误:

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

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

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

2 个答案:

答案 0 :(得分:1)

尽管iOS 13中的新模拟器支持Metal,但ARView要求实际设备才能捕获相机帧并生成传感器融合数据。而且它具有大量的属性和方法,您需要对其进行模拟才能与其他代码进行交互。

您能否通过另一个类(例如UIView或UIViewController子类)实现的协议来抽象SwiftUI之间的ARView交互?如果该协议足够简单,则可以创建一个可以模拟交互的类-无需实际使用整个ARView API,就可以像对待UIView一样实际地响应您的SwiftUI视图。

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

答案 1 :(得分:1)

我遇到了同样的问题。我的解决方案是使用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