大多数浏览器和
Developer App 均支持流媒体播放。
-
利用 SwiftUI 量身定制 macOS 窗口
为你的窗口打造专为 macOS 量身定制的使用体验。有侧重点地微调 App 的窗口,以便提升易用性并突显功能实用性。使用 SwiftUI 为窗口工具栏和背景设定合适的风格。精准排列你的窗口,并在窗口恢复和最小化方面做出明智的决策。
章节
- 0:53 - Anatomy of a window
- 1:53 - App window structure
- 2:41 - Style window toolbars
- 3:53 - Refine window behaviors
- 5:55 - Adjust window placement
资源
- Customizing window styles and state-restoration behavior in macOS
- Destination Video
- Forum: UI Frameworks
- Windows
相关视频
WWDC24
WWDC22
-
下载
嗨 我叫 Haotian 我是 SwiftUI 团队的 一名工程师 在本视频中 我将与大家分享 如何使用新的 SwiftUI API 来定制 macOS 应用程序窗口
早在 1984 年 Apple 便通过将桌面体验数字化 从而彻底改变了这一体验
从单色
到彩色
到 Aqua
再到后来 桌面体验始终是 macOS 体验的核心所在
窗口是绘制应用程序 用户界面的基本单位
一个典型的窗口由几个 可识别的组件构成
在窗口顶部 有一个工具栏 用于承载窗口控件、 标题和工具栏项
App 的主要内容 就位于工具栏后面 而背景则位于最后面 从而投射出阴影 以营造层次感和纵深感
接下来 我将向你展示 如何自定窗口中的这些元素 我会以“Destination Video”App 为例来进行讲解
这是一个 SwiftUI App 使用 Window 和 WindowGroup 等场景构建而成 用于整理和播放视频
如果你想详细了解 不同的场景类型 请查看“为你的 SwiftUI App 添加多个窗口” 和“在 SwiftUI 中设计窗口”
现在 我将使用 新的 SwiftUI API 进一步微调窗口 让窗口更契合 App 的内容
这是主窗口 它是用于浏览视频集合的主界面
这是“关于”窗口 用于显示应用程序版本和支持信息
这是视频播放器窗口 用于媒体播放
我将根据窗口所呈现的内容类型 来定制每个窗口 为此 我会更改窗口工具栏、 窗口行为和窗口位置
首先 我要自定 Destination Video 主窗口的工具栏
它是通过具有内容视图的 WindowGroup 来创建的
现在 这个窗口中显示了 工具栏和标题
根据我的设计 工具栏和标题下方有一张大图 为了突出这个图像 我要移除标题和工具栏背景 可以使用 .toolbar(removing) 修饰符 以及 .toolbarBackgroundVisibility() 修饰符
这时 大图延伸到了窗口的上边缘
即使标题已在用户界面中隐藏 但它仍与这个窗口关联 辅助功能和其他功能 都可使用这个标题
例如 主菜单项会继续显示窗口标题
只需几行代码 我便已完成工具栏元素自定 以适应我的设计 并突出窗口内容 接下来 我会优化 “关于”窗口的行为
每款 Mac App 都有“关于”窗口 可以从主菜单进行访问
“关于”窗口会显示这个 App 的 版本号和其他详细信息
对于 Destination Video 我决定创建一个自定“关于”窗口 以便与主目录窗口 的精简外观更为契合
首先 我会添加一些 上一部分用过的修饰符 来隐藏标题并移除工具栏背景
我用 .containerBackground() 修饰符 将窗口背景颜色替换为某一材料 以便为窗口增添些许风格 材料会呈现部分透明感 比如毛玻璃 让桌面的颜色可以透过窗口 显现出来
而绿色的“缩放”窗口控件则已停用 因为这个内容的尺寸固定
“关于”窗口可显示静态信息 且始终可从主菜单进行访问 因此 我想停用 黄色的“最小化”控件
使用 .windowMinimizeBehavior() 修饰符来停用这个控件
接着 我还会自定“关于”窗口的 状态恢复行为
状态恢复功能会在 App 退出时 保存窗口的尺寸和位置 然后 它会在 App 下次启动时 自动重新打开这些设置
SwiftUI App 中的窗口 会自动恢复 但我不希望“关于”窗口恢复 所以 使用 .restorationBehavior() 场景修饰符来停用这个功能
现在 我的窗口无论是外观 还是行为 都变得非常理想 最后 我会调整这些窗口 在屏幕上的确切显示位置
对于视频播放器窗口来说 这一步尤其重要
这个窗口的理想尺寸 取决于播放的视频 以及播放视频的屏幕 在这里 蓝色实线框表示 播放的视频 黄色虚线框表示播放视频的屏幕
视频的尺寸可能不尽相同
有些视频很小 可轻松适配屏幕尺寸
有些视频可能在一个或两个维度上 超出屏幕尺寸 这是因为视频或屏幕 采用了竖屏格式
播放功能需与任意数量的 外部显示器配置搭配使用
对于我的视频播放器窗口 我希望 它能根据视频和播放视频的屏幕 找到最合适的位置和尺寸
首先 我会为新创建的播放器窗口 指定一个初始位置 我可以使用 .defaultWindowPlacement 修饰符
这个修饰符可接受 附带两个参数的闭包:
一个是代理视图 用于查询内容尺寸 另一个是上下文值 包含有关显示的信息
对内容调用 .sizeThatFits() 算出窗口的理想尺寸 然后 从显示区域获取 visibleRect 得出可用区域 整个操作会自动考虑到菜单栏 和程序坞占用的所有空间
这个视频应以原始尺寸进行显示 但如果这个尺寸对于屏幕来说过大 则应按比例缩小以适应屏幕尺寸
我会返回具有这个尺寸 而无显式位置的放置位置
这个窗口默认会居中显示
此外 我还需考虑 视频播放器窗口处于打开状态时 可调整窗口尺寸的不同方式
例如 从“窗口”菜单选择“缩放” 可自动放大窗口 如果再次选择“缩放”
则会将窗口恢复为先前的尺寸
.windowIdealPlacement 修饰符 可用于控制缩放窗口的放大比例
我的目标是确保 缩放后的窗口能尽可能放大 同时还能保持理想的宽高比
我提供的闭包与用来寻找 理想位置的闭包类似 和之前一样 我会用上下文值 来计算显示屏的可见区域
这一次 我想扩大这个窗口 以适应显示尺寸 为此 我会用 zoomToFit 辅助函数
通过这几项更改 视频播放器窗口能够更好地适应 视频内容和显示屏幕
通过自定 App 窗口 现在每个窗口都能带来 与各自用途更契合的体验
几个新的 API 就能够带来很大的改变
在 macOS Sequoia 中 还有更多窗口自定选项可供探索
例如 你可使用简约窗口样式 来构建无边框窗口
或者 也可打造类似欢迎窗口 这样的体验 以便在启动时有条件地 率先显示相关窗口
这只是几个例子 希望它们能为你的项目带来启发
接下来 你可以 设置工具栏样式 来完善窗口的内容和用途
优化窗口行为以匹配 App 窗口的功能
还可以微调窗口位置 从而为所有显示配置 提供出色的体验 请查看 SwiftUI 文档 并试用新的 API 来实现你的设计目标
感谢观看 说不定你正在通过无边框视频窗口 来观看我的讲座!
-
-
3:11 - Style Toolbars - Removing Title
.toolbar(removing: title)
-
3:14 - Style Toolbars - Removing Toolbar Background
.toolbarBackgroundVisibility(.hidden, for: .windowToolbar)
-
4:33 - Refine Behaviors - Adding Container Background
.containerBackground(.thickMaterial, for: .window)
-
5:13 - Refine Behaviors - Minimize Behavior
.windowMinimizeBehavior(.disabled)
-
5:44 - Refine Behaviors - Restoration Behavior
.restorationBehavior(.disabled)
-
7:11 - Adjust Placement - Default Placement
.defaultWindowPlacement { content, context in var size = content.sizeThatFits(.unspecified) let displayBounds = context.defaultDisplay.visibleRect // modify size based on display bounds return WindowPlacement(size: size) }
-
8:35 - Adjust Placement - Ideal Placement
.windowIdealPlacement { content, context in var size = content.sizeThatFits(.unspecified) let displayBounds = context.defaultDisplay.visibleRect // modify size based on display bounds return WindowPlacement(size: size) }
-
9:48 - Borderless Window
.windowStyle(.plain)
-
9:53 - Default Launch Behavior
.defaultLaunchBehavior(.presented)
-
-
正在查找特定内容?在上方输入一个主题,就能直接跳转到相应的精彩内容。
提交你查询的内容时出现错误。请检查互联网连接,然后再试一次。