前言
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 提供的沉浸式体验的另一种方法是使用 transform3DEffect 和 rotation3DEffect 视图修改器来加入深度效果。如下图:
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 应用程序提供了强大而灵活的工具,我们可以期待在这个全新的平台上开发出令人惊叹的应用体验。