VisionPro开发 - 窗口位置和尺寸


首页:漫游Apple Vision Pro

Code Repo: github.com/xuchi16/vis...

Project Path: github.com/xuchi16/vis...


窗口,空间容器和空间 中我们了解了如何在 visionOS 中打开新的窗口。但在默认的实现中,无论是最初的导航窗口还是后续打开的新窗口,它们的大小和位置未必满足需求。

为了控制窗口的位置和尺寸,需要通过 modifier 控制初始的窗口位置。

二维窗口(Window)

初始情况

初始 visionOS 项目页面如下,有一个ContentView,其中包含了一个 3D 的模型和一个按钮。并在 App 中,定义了一个WindowGroup来渲染ContentView。在 visionOS 中,默认会打开 App 类中定义的第一个 Scene,这里就是ContentView

swift 复制代码
// PositionAndSizeApp.swift
@main
struct PositionAndSizeApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
    }
}

这时,窗口的行为:

  • 初始状态:打开的面积太大
  • 缩放行为:可以任意缩放,太大了内容偏小,太小了会裁切(clipping)掉部分内容

理解概念

首先需要先理解 View 和 Window 的关系,

View: A type that represents part of your app's user interface.

Windows: Display user interface content in a window or a collection of windows.

  • View:应用中的一组 UI 元素构成一个视图,可以嵌套,是构建整个应用的基础

  • Windows:是一个窗口,用来容纳 View。包括 Window 和 WindowGroup。其中 visionOS 并不支持 Window,而只支持 WindowGroup。

直观地举个例子,如果在 WindowGroup 中定义 2 个 View,则实际展示会变成一个窗口里堆叠了 2 个同样的 View。

swift 复制代码
// PositionAndSizeApp.swift
@main
struct PositionAndSizeApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
            ContentView()  // Duplicate the previous view
        }
    }
}

控制大小

初始大小

这里我们需要控制的是 Window 而非 View,因此通过 Window 的.defaultSize modifier 即可指定大小。

swift 复制代码
 @main
struct PositionAndSizeApp: App {

    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .defaultSize(CGSize(width: 800, height: 600))
    }
}

缩放行为

控制缩放则是通过 2 个步骤的配合来完成的

  • 控制 View 的 frame 大小
  • 控制 Window 的缩放类型,即.windowResizability

其中,.windowResizability提供了 3 种类型

  • automatic:不控制,这也是默认的控制类型
  • contentSize:根据窗口中的内容决定缩放大小
  • contentMinSize:根据窗口中的内容部分控制,只控制缩放到最小的情况,不控制放大
swift 复制代码
 @main
struct PositionAndSizeApp: App {
    private var defaultWidth = 800.0
    private var defaultHeight = 600.0
    private var expandRatio = 1.6
    private var shrinkRatio = 0.8
    
    var body: some Scene {
        WindowGroup {
            ContentView()
            .frame(
                minWidth: defaultWidth * shrinkRatio, maxWidth: defaultWidth * expandRatio,
                minHeight: defaultHeight * shrinkRatio, maxHeight: defaultHeight * expandRatio)
        }
        .windowResizability(.contentSize)
        .defaultSize(CGSize(width: defaultWidth, height: 600))
        
        ImmersiveSpace(id: "ImmersiveSpace") {
            ImmersiveView()
        }
    }
}

这里我们通过上述两步,即可以达到如下效果:

  • 初始状态:按照设定大小打开
  • 缩放行为 :有最大和最小边界

空间容器(Volume)

当我们在初始窗口中打开一个新的 Volume 窗口时,会发现

  • 位置:默认出现的位置
  • 大小:尽管 3D 模型很小,但默认的 Volume 窗口很大,控制器离物体很远

类似于 2D 窗口,也可以通过.defaultSize modifier 控制空间容器窗口的大小。

默认情况

指定初始大小

指定位置

You can't use defaultPosition(_:) in visionOS. The system always places new windows directly in front of people, where they happen to be looking at the moment the window opens. This helps to make people aware of new windows.

在 macOS 中,可以通过defaultPosition(_:)来控制窗口打开时的位置,如打开在页面底部。但 visionOS 中,窗口总是在用户面前打开,从而让用户意识到了有新的窗口,因此并不支持指定打开位置。

相关推荐
HarderCoder7 个月前
Apple Vision Pro 学习资料
visionos
苹果API搬运工7 个月前
试玩 RealityComposerPro 中的 Shader Graph:用圆环制作一个 Meta Logo
visionos·增强现实
苹果API搬运工7 个月前
我开源了个手势匹配框架,让你在模拟器调试 visionOS 手部追踪功能!
visionos·增强现实
苹果API搬运工7 个月前
只需三板斧!带你入门 visionOS 空间计算的数学与几何基础
visionos·增强现实
-九月新辰-7 个月前
Unity VisionOS开发流程
unity·游戏引擎·visionos
XR基地8 个月前
XR 世界导览021 | AVP App Store上线网页版、如何在AVP上快速匹配手势、AVP开发岗位
visionos
XR基地8 个月前
XR 世界导览#020-visionOS 1.1/Xcode 17.3/PICO 5.9.0 更新了!
unity3d·visionos
xChester8 个月前
visionOS 应用图标设计
前端·ios·visionos
XR基地8 个月前
XR 世界导览#019-Let's visionOS 大会/在 AVP 上玩手机或查看Spline的3D模型/用代码写ShaderGraph
unity3d·visionos
xChester9 个月前
VisionPro开发 - 轻松实现天空盒并添加光照
前端·ios·visionos