Shaft多窗口终极指南:用SubWindow快速创建独立原生窗口
2026/8/23 13:57:03 网站建设 项目流程

Shaft多窗口终极指南:用SubWindow快速创建独立原生窗口

【免费下载链接】ShaftA cross-platform GUI framework for Swift, built for demanding workloads and developer ergonomics项目地址: https://gitcode.com/gh_mirrors/sh/Shaft

Shaft 是一个面向 Swift 的跨平台 GUI 框架,而它的SubWindow组件正是多窗口开发的利器——只需几行代码,就能为主窗口之外弹出独立运行的原生窗口,每个窗口拥有独立的控件层级,互不干扰。

如图所示,Shaft 可以同时在屏幕上运行多个独立窗口,它们各自渲染不同的页面内容,这就是SubWindow提供的原生多窗口能力。

什么是 Shaft 的 SubWindow?

SubWindow是一个StatefulWidget,它在被渲染时会自动通过后端(Shaft.Backend)创建一个新的原生视图,并把子控件渲染进去。你可以把它理解为:主窗口里的一个按钮,点一下就能开一个新窗口——而且新窗口完全由框架托管,无需手写平台代码。

它的核心定义位于 View.swift:

public final class SubWindow: StatefulWidget { public init( onCreateWindow: OnCreateWindow? = nil, onWindowCreated: OnWindowCreated? = nil, onWindowDestroyed: OnWindowDestroyed? = nil, @WidgetBuilder child: () -> Widget ) }

三个回调各司其职:

回调触发时机典型用途
onCreateWindow窗口创建前自定义创建逻辑,返回已有原生视图
onWindowCreated窗口创建成功后设置标题、大小、位置等属性
onWindowDestroyed窗口销毁前保存状态、清理资源

一键创建独立原生窗口

创建子窗口最简单的写法,就是把内容包进SubWindow即可。官方示例见 Demo_MultiWindow.swift:

SubWindow( onWindowCreated: { view in if let view = view as? DesktopView { view.title = "My Window" view.size = .init(400, 400) } } ) { Text("Sub Window 1") .center() .background(.init(0xFFFF_FFFF)) }

这段代码会在主界面下方弹出一个 400×400 的独立窗口,里面居中显示一行文字。子窗口渲染时会通过内部的BoxToViewAdapter自动适配布局约束,你写的控件代码和在主窗口中完全一样,无需任何特殊处理。

快速配置窗口属性

在桌面平台上,创建回调返回的视图实现了DesktopView协议(定义见 Backend.swift),你可以在onWindowCreated中直接配置这些属性:

  • title:窗口标题
  • size/position:窗口大小与左上角位置
  • alwaysOnTop:是否置顶显示
  • visible:窗口是否可见
  • displayID:窗口所在的显示器(支持多屏场景)
  • requestFocus():主动请求键盘焦点
onWindowCreated: { view in if let view = view as? DesktopView { view.position = .init(100, 100) view.alwaysOnTop = true // 悬浮提示窗口常用技巧 } }

这套属性让"悬浮通知面板""多屏看板"这类需求都能轻松实现,而且代码完全跨平台——Windows、Linux、macOS 上行为一致。

窗口生命周期回调:创建与销毁

SubWindow帮你管好窗口的整个生命周期,框架内部实现见 View.swift:

  1. initState阶段:调用backend.createView()创建原生窗口,随后触发onWindowCreated
  2. 渲染阶段:子控件作为新窗口的根内容渲染;
  3. dispose阶段:窗口不再需要时,先触发onWindowDestroyed,再调用backend.destroyView()销毁窗口。

也就是说,只要SubWindow从 widget 树中移除,对应的原生窗口就会自动关闭并释放——不存在窗口泄漏的顾虑。用户手动点掉窗口、或你通过条件渲染移除它,都走同一条清理路径。

自定义窗口创建:onCreateWindow

如果默认创建方式不够用(比如你想复用某个已存在的原生视图),可以实现onCreateWindow回调,手动返回一个NativeView

SubWindow( onCreateWindow: { // 返回自定义创建的原生视图,返回 nil 则放弃创建 customBackend.createView() } ) { Text("Custom window") }

这正是 Shaft 模块化设计的体现:Backend 层抽象了平台差异,你甚至可以为特殊场景(如终端 UI、Wayland 合成器)实现自己的后端。整体分层如下图所示——SubWindow依赖的createView/destroyView就位于Shaft.Backend协议中。

亲自动手:运行官方 Multi Window 演示

想立刻体验?三步即可跑起来:

git clone https://gitcode.com/gh_mirrors/sh/Shaft cd Shaft swift run Playground

启动后,在左侧导航栏的Demos分组中点击Multi Window(菜单注册见 main.swift),即可看到子窗口弹出的完整演示,页面内还附带了分步讲解。

💡 小贴士:Playground 应用本身就是一个可交互的文档,每个演示页都包含原理说明和可复制的代码片段。

为什么选择原生多窗口?

  • 零平台代码:不写一行 Cocoa 或 Win32,Swift 控件直接渲染进原生窗口;
  • 独立渲染:每个窗口拥有独立的 widget 层级与事件循环接入,主窗口卡顿不影响子窗口;
  • 生命周期托管:创建、销毁、内存回收全部由框架处理;
  • 跨平台一致:同一份代码在 Windows、Linux、macOS 表现相同。

总结

SubWindow让 Shaft 的多窗口开发回归了声明式的简洁:一个组件、三个可选回调、一段普通控件代码,就能弹出可配置的独立原生窗口。无论你是想做一个悬浮面板、弹出式工具窗口,还是多屏协同应用,它都是 Swift 跨平台开发中最省心的多窗口方案。

【免费下载链接】ShaftA cross-platform GUI framework for Swift, built for demanding workloads and developer ergonomics项目地址: https://gitcode.com/gh_mirrors/sh/Shaft

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询