Highlight
visionOS 的 Quick Look 新增 PreviewApplication API,可以用几行代码打开窗口化预览;3D 模型支持 Surface Mapping 自动吸附桌面,USDZ 的 variants 机制可以在单个文件中切换多个配色方案。
核心内容
在 visionOS 上预览文件有两种方式:内嵌式(作为全屏 cover 覆盖你的 app)和窗口式(在独立 volume 中展示,用户可以同时操作你的 app)。但窗口式体验之前只能通过拖拽触发,app 对预览过程几乎没有控制力——不能指定标题、不能关闭编辑选项、也不知道用户什么时候关闭了预览。
今年 Apple 推出了 PreviewApplication API,基于 SwiftUI 和 Swift Concurrency 构建。调用 PreviewApplication.open 传入 URL 就能打开窗口化预览,传入 URL 数组则打开集合视图,带前后导航箭头。通过 PreviewItem 可以自定义标题(displayName)和编辑模式(editingMode),比如 .disabled 会移除裁剪、修剪等编辑按钮。API 返回一个 session 对象,它的 events 是 Swift async stream,可以监听预览的打开和关闭事件。
3D 内容方面,两个呼声最高的功能落地了。Surface Mapping 让任何 3D 模型自动吸附到桌面或地板——拖动窗口栏靠近桌面即可触发,吸附后可以自由滑动模型,期间锁定俯仰旋转防止模型穿入桌面。Configurations(USDZ 中叫 variants)允许在一个文件中包含多个变体,比如不同颜色的 iPhone,用户在 Quick Look 中直接切换,不用为每个配色单独准备文件。这个功能在 iOS 和 macOS 上同样可用,visionOS 上还支持 FaceTime 通话中同步配置切换。
详细内容
PreviewApplication API
最基本的用法:给 PreviewApplication.open 传入单个文件的 URL(02:53)。
PreviewApplication.open(url: selectedURL)
传入 URL 数组可以打开集合视图(03:48):
PreviewApplication.open(urls: allURLs, selectedURL: selectedURL)
- 关键点:
urls参数接收数组,Quick Look 展示集合视图并提供导航箭头selectedURL指定初始聚焦的文件
用 PreviewItem 自定义标题和编辑模式(05:19):
let previewItem = PreviewItem(url: selectedURL, displayName: entryName, editingMode: .disabled)
PreviewApplication.open(previewItem: previewItem)
- 关键点:
displayName显示在 Quick Look 顶部菜单栏editingMode: .disabled移除编辑按钮,防止用户误修改原始文件- 其他 editingMode 选项详见 API 文档
通过 session 的 events 管理预览生命周期(06:47):
let session = PreviewApplication.open(url: selectedURL)
for await event in session.events {
switch event {
case .opened:
isPreviewOpen = true
case .closed:
isPreviewOpen = false
}
}
- 关键点:
session.events是 Swift AsyncSequence,用for await迭代.opened和.closed事件让你在 UI 上同步预览状态- 重复打开同一文件不会创建新窗口,只把已有窗口带到前台
USDZ Variants(Configurations)
USDZ 中用 variantSet 定义配置变体(12:22):
#usda 1.0
(
defaultPrim = "iPhone"
)
def Xform "iPhone" (
variants = {
string Color = "Black_Titanium"
}
prepend variantSets = ["Color"]
)
{
variantSet "Color" = {
"Black_Titanium" { }
"Blue_Titanium" { }
"Natural_Titanium" { }
"White_Titanium" { }
}
}
- 关键点:
- 所有 variants 必须定义在
defaultPrim上,Quick Look 才能正确查询和展示 string Color = "Black_Titanium"设置默认变体prepend variantSets = ["Color"]声明变体集合的名称- variant 名不支持空格,用下划线代替,Quick Look 自动转换为空格显示
- Quick Look 底部出现配置按钮,用户点选后模型重新加载为对应变体
- 避免在变体中包含重纹理或复杂几何体,以免影响加载速度
- 所有 variants 必须定义在
Surface Mapping
- 所有 3D 模型自动启用 Surface Mapping,无需额外代码
- 支持水平表面(桌面、地板)
- 拖动窗口栏靠近表面时触发吸附,伴随提示音
- 吸附后锁定俯仰旋转(pitch),防止模型穿入表面
- 导出 USDZ 时确保模型底部落在坐标原点上,吸附效果才正确
核心启发
-
用 PreviewApplication.open 替代内嵌式 Quick Look:窗口化预览不打断用户当前操作,支持多任务;代码量从 SwiftUI 的 fullScreenCover + UIViewControllerRepresentable 减少到一行调用。在缩略图的
onTapGesture中调用PreviewApplication.open(url:)即可。 -
制作包含 variants 的 USDZ 文件:一个文件包含所有配色,用户在 Quick Look 中直接切换,减少文件数量和管理成本;visionOS 上的 FaceTime 还支持配置同步。在 USDZ 的 defaultPrim 上定义
variantSet,每个变体对应一个配置,变体名用下划线替代空格。 -
确保 3D 模型底部对齐坐标原点:Quick Look 的 Surface Mapping 默认对所有模型启用,如果模型底部不在原点上,吸附到桌面后会出现悬浮或穿入。在 3D 建模软件中导出前将模型整体下移,使底面落在 Y=0 平面。
-
用 session.events 在 UI 上标注正在预览的文件:用户打开多个预览后容易忘记哪些在查看中,用眼睛图标等视觉标记可以清晰指示状态。存储
PreviewApplication.open返回的 session,在for await event in session.events中更新状态变量驱动 UI 刷新。
关联 Session
- Build compelling spatial photo and video experiences — 了解如何在 app 中创建和采用空间照片与视频
- Optimize your 3D assets for spatial computing — 3D 资产优化工作流,减少变体加载时间的关键技巧
- What’s new in USD and MaterialX — USD 格式的最新更新,variants 机制的底层技术支撑
- Dive deep into volumes and immersive spaces — 深入理解 volume 的定制方式,Quick Look 窗口化预览的底层容器
评论
GitHub Issues · utterances