视频经过solar system 这个项目解说SwiftUI 在visionOS的入门操作。
构建空间app需要运用swiftUI,苹果扩展了swiftUi功用,并能和RealityKit深度配合。
从Windows、Volumes、Full Spaces三个方面介绍swiftUI实现的一些比如。

WWDC23 Meet SwiftUI for spatial computing
Button("Of course") {
  // perform action
}
Toggle(isOn: $favorite) {
    Label("Favorite", systemImage: "star")
}
TabView {
    DogsTab()
        .tabItem {
            Label("Dogs", systemImage: "pawprint")
        }
    CatsTab()
        .tabItem {
            Label("Cats", image: "cat")
        }
    BirdsTab()
        .tabItem {
            Label("Birds", systemImage: "bird")
        }
}
WWDC23 Meet SwiftUI for spatial computing
WWDC23 Meet SwiftUI for spatial computing

经过上面代码简略介绍visionOS 上demo的基本按钮、点击作用和简略tab。经过上面比如能够看出用swiftUI在visionOS 上很简略。

  • windows

简略代码示例:

@main
struct WorldApp: App {
    var body: some Scene {
        WindowGroup("Hello, world") {
            ContentView()
        }
    }
}

WWDC23 Meet SwiftUI for spatial computing
每个window相似本来app 的是一个视图
在window上能够运用相似本来app的导航结构和相似iPad 上app的左右分组。还能够运用左测list来对内容分组导航。

WWDC23 Meet SwiftUI for spatial computing

— Ornaments window 外的view成为“装修”

WWDC23 Meet SwiftUI for spatial computing

visonOS 没有light 和dark模式了,原有Material来决定。、 如下面代码 regularMaterial

VStack(alignment: .leading, spacing: 12) {
    Text("Stats")
        .font(.title)
    StatsGrid(stats: stats)
        .padding()
        .background(.regularMaterial, in: .rect(cornerRadius: 12))
}

在交互模式上,能够运用眼睛、手势还有Pointer、Accessibility。系统还支撑外接键盘。

WWDC23 Meet SwiftUI for spatial computing

swiftiUi 还支撑一些新手势交互。

WWDC23 Meet SwiftUI for spatial computing

swiftiUI accessibility 也适配了visionOS

WWDC23 Meet SwiftUI for spatial computing
例如Dwell control 只能运用眼神。

悬停作用

WWDC23 Meet SwiftUI for spatial computing

代码示例: FunFactButtonStyle 中的hoverEffect

Button(action: {
    // perform button action
}) {
    VStack(alignment: .leading, spacing: 12) {
        Text(fact.title)
            .font(.title2)
            .lineLimit(2)
        Text(fact.details)
            .font(.body)
            .lineLimit(4)
        Text("Learn more")
            .font(.caption)
            .foregroundStyle(.secondary)
    }
    .frame(width: 180, alignment: .leading)
}
.buttonStyle(.funFact)
struct FunFactButtonStyle: ButtonStyle {
    func makeBody(configuration: Configuration) -> some View {
        configuration.label
            .padding()
            .background(.regularMaterial, in: .rect(cornerRadius: 12))
            .hoverEffect()
            .scaleEffect(configuration.isPressed ? 0.95 : 1)
    }
}

针对vison app 需要增加装修和悬停作用

WWDC23 Meet SwiftUI for spatial computing

  • Volumes Volumes 代码创建示例
  @main
struct WorldApp: App {
    var body: some Scene {
        WindowGroup {
            Globe()
        }
        .windowStyle(.volumetric)
        .defaultSize(width: 600, height: 600, depth: 600)
    }
}  // 全局设置

3D 作用引进

import SwiftUI
import RealityKit
struct Globe: View {
    var body: some View {
        Model3D(named: "Earth")
    }
}

有些相似加载图片

WWDC23 Meet SwiftUI for spatial computing

3d 对象相关控制代码

struct Globe: View {
    @State var rotation = Angle.zero
    var body: some View {
        ZStack(alignment: .bottom) {
            Model3D(named: "Earth")
                .rotation3DEffect(rotation, axis: .y)
                .onTapGesture {
                    withAnimation(.bouncy) {
                        rotation.degrees += randomRotation()
                    }
                }
                .padding3D(.front, 200)
            GlobeControls()
                .glassBackgroundEffect(in: .capsule)
        }
    }
    func randomRotation() -> Double {
        Double.random(in: 360...720)
    }
}

RealityView 引进示例 经过RealityView 引进能够运用RealityView丰厚的api

RealityView { content in
    if let earth = try? await
        ModelEntity(named: "Earth")
    {
       earth.addImageBasedLighting()
       content.add(earth)
    }
}

苹果建议在SiwiftUI Views 运用realityKit。能够参加丰厚的阴影、物理等行为。 经过SpatialTapGesture 给reality View 加手势

struct Earth: View {
		@State private var pinLocation: GlobeLocation?
    var body: some View {
        RealityView { content in
            if let earth = try? await
                ModelEntity(named: "Earth")
            {
               earth.addImageBasedLighting()
               content.add(earth)
            }
        }
				.gesture(
            SpatialTapGesture()
                .targetedToAnyEntity()
                .onEnded { value in
                    withAnimation(.bouncy) {
                        rotation.degrees += randomRotation()
                        animatingRotation = true
                    } completion: {
                        animatingRotation = false
                    }
                    pinLocation = lookUpLocation(at: value)
                }
        )
    }
}

加attachments

struct Earth: View {
		@State private var pinLocation: GlobeLocation?
    var body: some View {
        RealityView { content in
            if let earth = try? await
                ModelEntity(named: "Earth")
            {
               earth.addImageBasedLighting()
               content.add(earth)
            }
        } update: { content, attachments in
            if let pin = attachments.entity(for: "pin") {
                content.add(pin)
                placePin(pin)
            }
        } attachments: {
            if let pinLocation {
                GlobePin(pinLocation: pinLocation)
                    .tag("pin")
            }
        }
				.gesture(
            SpatialTapGesture()
                .targetedToAnyEntity()
                .onEnded { value in
                    withAnimation(.bouncy) {
                        rotation.degrees += randomRotation()
                        animatingRotation = true
                    } completion: {
                        animatingRotation = false
                    }
                    pinLocation = lookUpLocation(at: value)
                }
        )
    }
}
  • Full Spaces

full spaces设置

@main
struct WorldApp: App {
    var body: some Scene {
				// (other WindowGroup scenes)
        ImmersiveSpace(id: "solar-system") {
            SolarSystem()
        }
    }
}

WWDC23 Meet SwiftUI for spatial computing

增加button

@Environment(\.openImmersiveSpace)
private var openImmersiveSpace
Button("View Outer Space") {
    openImmersiveSpace(id: "solar-system")
}

经过RealityView 加一个星空布景

struct Starfield: View {
    var body: some View {
        RealityView { content in
            let starfield = await loadStarfield()
            content.add(starfield)
        }
    }
}
struct SolarSystem: View {
    var body: some View {
        Earth()
        Sun()
      	Starfield()
    }
}

WWDC23 Meet SwiftUI for spatial computing

运用ARKit 能够带来更多体会

WWDC23 Meet SwiftUI for spatial computing

WWDC23 Meet SwiftUI for spatial computing