一、创建项目
我这里用的是Xcode15-beta8, 模拟器用的是visionOS_1_beta_3
- 通过Xcode -> File -> New -> Project来创建项目
- 选择visionOS这个tab 然后选择 下面的App
- 进一步选择一下初始的模板
这里 Inital Scene 选择Window,Immersive Space Render选择RealityKit,Immersive Space选择Mixed。
二、创建列表视图
我们可以看到一开始的模板代码和Preview的效果
php
VStack {
Model3D(named: "Scene", bundle: realityKitContentBundle)
.padding(.bottom, 50)
Text("Hello, world!")
Toggle("Show Immersive Space", isOn: $showImmersiveSpace)
.toggleStyle(.button)
.padding(.top, 50)
}
.padding()
.onChange(of: showImmersiveSpace) { _, newValue in
Task {
if newValue {
switch await openImmersiveSpace(id: "ImmersiveSpace") {
case .opened:
immersiveSpaceIsShown = true
case .error, .userCancelled:
fallthrough
@unknown default:
immersiveSpaceIsShown = false
showImmersiveSpace = false
}
} else if immersiveSpaceIsShown {
await dismissImmersiveSpace()
immersiveSpaceIsShown = false
}
}
}
添加3D模型资源
双击打开Packages -> RealityKitContent -> Package, 然后再点击右上角的Open in Reality Composer Pro
然后把之前生成好的 usdz文件拖进来就可以了。
编写列表视图代码
我们可以继续保留模板,但是把View中的内容替换成我们要去创建的视图。
代码如下:
scss
NavigationSplitView {
List(0..<30, id: .self, selection: self.$selection) { i in
HStack(alignment: .top) {
Model3D(named: "Speedy", bundle: realityKitContentBundle)
Text("ID: (i)")
Text("路易威登 NeoNoe背包")
}
}
} detail: {
ItemDetailView()
}
这里通过一个NavigationSplitView来包裹一个List视图,List中的每一个列表项由三部分组成:
-
3D模型
-
ID文本
-
标题文本
这里使用Model3D来加载3D模型,通过named参数跟刚刚在 Reality Composer Pro中导入的模型进行关联。
但是当我以这样的方式展示时,发现3D模型按照他原有的尺寸展示太大了,把文本都挤出去了,这个时候我就想到了需要进行缩放。
3D模型缩放
我这里用到的缩放方式是:
less
Model3D(named: "Speedy", bundle: realityKitContentBundle)
.scaleEffect(x: 0.1, y: 0.1, z: 0.1)
这个时候会发现,3D模型是已经缩放了,但是还是占据了过大的空间,导致列表中无法显示其他内容。所以这里需要设定3D模型视图的框架尺寸。
设置3D模型框架的尺寸
less
Model3D(named: "Speedy", bundle: realityKitContentBundle)
.frame(width: 10, height: 10)
.scaleEffect(x: 0.1, y: 0.1, z: 0.1)
这个时候发现,尺寸是正确了,整个列表的空间也正常了。 但是,这个3D模型怎么漂浮在空中呢?经过查资料之后,发现Model3D还可以通过设置一个depth的维度,来控制其Z轴的尺寸。
less
Model3D(named: "Speedy", bundle: realityKitContentBundle)
.frame(depth: 1, alignment: .center)
.frame(width: 10, height: 10)
.scaleEffect(x: 0.1, y: 0.1, z: 0.1)
.padding(.init(top: 0, leading: 10, bottom: 0, trailing: 10))
通过以上代码,再加上padding,这个列表的布局基本OK了
但是这里还有一个很奇葩的问题,就是我的3D模型太暗了
左边是原始模型,右边是渲染后的模型,应该是跟光线相关的设置。结果网上找了一圈资料没找到相关信息,用模拟器跑起来就好了。。看来是Preview的问题。
到这里,基础的列表展示就完成了。后续实践将进行详情视图的编写,以及Immersive视图的编写。
参考文章
stackoverflow.com/questions/7...