前语

Apple Vision Pro 行将推出,现在是看看 SwiftUI API 的完美机遇,这使咱们能够将咱们的运用程序习惯 visionOS 供给的沉溺式国际。苹果表明,构建运用程序的最佳方法是运用 Swift 和 SwiftUI。下面,咱们将学习怎么运用 SwiftUI 构建 visionOS 运用程序。

Windows

我喜爱 SwiftUI 的一点是它怎么主动习惯平台。你无需执行任何操作即可在 visionOS 上运行运用 SwiftUI 编写的运用程序。它能够即插即用。可是,你一直能够经过向前移动并习惯平台功能来改进用户体会。

struct ContentView: View {
    var body: some View {
        NavigationSplitView {
            List {
            // 列表内容
            }
            .navigationTitle("Models")
            .toolbar {
                ToolbarItem(placement: .bottomOrnament) {
                    Button("open", systemImage: "doc.badge.plus") {
                    }
                }
                ToolbarItem(placement: .bottomOrnament) {
                    Button("open", systemImage: "link.badge.plus") {
                    }
                }
            }
        } detail: {
            Text("Choose something from the sidebar")
        }
    }
}

在上面的示例中,咱们运用了称为 bottomOrnament 的新东西栏放置。 visionOS 中的装修是坐落窗口外部的方位,用于出现与窗口衔接的控件。你还能够经过运用新的 ornament 视图修改器手动创立它们。

struct ContentView: View {
    var body: some View {
        NavigationSplitView {
            List {
            // 列表内容
            }
            .navigationTitle("Models")
            .ornament(attachmentAnchor: .scene(.leading)) {
                // 在此处放置你的视图
            }
        } detail: {
            Text("Choose something from the sidebar")
        }
    }
}

新的 ornament 视图修改器答应咱们为其衔接的窗口创立一个具有特定锚点的装修。将你的运用内容习惯 visionOS 供给的沉溺式体会的另一种方法是运用 transform3DEffectrotation3DEffect 视图修改器来加入深度效果。如下图:

怎么运用 SwiftUI 构建 visionOS 运用

Volumes

你的运用程序能够在 visionOS 上的同一场景中并排显现 2D 和 3D 内容。在这种情况下,咱们能够运用 RealityKit 框架来出现 3D 内容。例如,RealityKit 为咱们供给了 Model3D SwiftUI 视图,答应咱们从 USDZ 或实践文件中显现 3D 模型。

struct ContentView: View {
    var body: some View {
        NavigationSplitView {
            List(Model.all) { model in
                NavigationLink {
                    Model3D(named: model.name)
                } label: {
                    Text(verbatim: model.name)
                }
            }
            .navigationTitle("Models")
        } detail: {
            Model3D(named: "robot")
        }
    }
}

Model3D 视图的工作方法类似于 AsyncImage 视图,并异步加载模型。你还能够运用 Model3D 初始化器的另一种变体,它答应你自界说模型装备并增加占位视图。

struct ContentView: View {
    var body: some View {
        NavigationSplitView {
            List(Model.all) { model in
                NavigationLink {
                    Model3D(
                        url: Bundle.main.url(
                            forResource: model.name,
                            withExtension: "usdz"
                        )!
                    ) { resolved in
                        resolved
                            .resizable()
                            .aspectRatio(contentMode: .fit)
                    } placeholder: {
                        ProgressView()
                    }
                } label: {
                    Text(verbatim: model.name)
                }
            }
            .navigationTitle("Models")
        } detail: {
            Model3D(named: "robot")
        }
    }
}

在你的运用程序中出现 3D 内容时,你能够运用 windowStyle 修饰符来启用内容的体积显现。体积款式答应你的内容在第三维中增长,以匹配模型的巨细。

关于更复杂的 3D 场景,咱们能够运用 RealityView 并填充它以 3D 内容。

struct ContentView: View {
    var body: some View {
        NavigationSplitView {
            List(Model.all) { model in
                NavigationLink {
                    RealityView { content in
                        // load the content and add to the scene
                    }
                } label: {
                    Text(verbatim: model.name)
                }
            }
            .navigationTitle("Models")
        } detail: {
            Text("Choose something from the sidebar")
        }
    }
}

沉溺式空间

visionOS 的第三个选项是完全沉溺式体会,答应咱们经过躲藏周围的所有内容来专注于你的场景。

@main
struct MyApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        ImmersiveSpace(id: "solar-system") {
            SolarSystemView()
        }
    }
}

正如你在上面的示例中所看到的,咱们经过运用 ImmersiveSpace 类型来界说场景。它答应咱们经过运用 openImmersiveSpace 环境值来启用它。

struct MyMenuView: View {
    @Environment(.openImmersiveSpace) private var openImmersiveSpace
    var body: some View {
        Button("Enjoy immersive space") {
            Task {
                await openImmersiveSpace(id: "solar-system")
            }
        }
    }
}

咱们还能够运用 dismissImmersiveSpace 环境值来封闭沉溺式空间。请记住,你一次只能显现一个沉溺式空间。

struct SolarSystemView: View {
    @Environment(.dismissImmersiveSpace) private var dismiss
    var body: some View {
        // Immersive experience
        Button("Dismiss") {
            Task {
                await dismiss()
            }
        }
    }
}

结论

在介绍了 SwiftUI 在 visionOS 上的运用之后,咱们了解到 SwiftUI 能够协助咱们轻松构建习惯 visionOS 的运用程序。不仅如此,SwiftUI 还供给了许多便利的东西和修饰符,例如 windowStyle 修饰符,可用于在运用程序中出现 3D 内容,并使内容根据模型的巨细主动习惯。经过引进沉溺式空间,咱们能够将用户带入全新的体会,让他们沉溺在运用程序的国际中。总的来说,SwiftUI 为构建 visionOS 运用程序供给了强壮而灵敏的东西,咱们能够期待在这个全新的平台上开发出令人惊叹的运用体会。