SwiftUI开发macOS应用:能否动态调整窗口大小?
macOS 窗口动态调整尺寸:可行方案与示例
完全可行,不管你用SwiftUI还是传统AppKit框架,都能轻松实现窗口在特定场景下放大、其他场景恢复原始尺寸的需求。以下是两种主流框架的实现示例:
SwiftUI 实现方式
核心逻辑是存储窗口的原始尺寸,根据场景状态切换目标尺寸,调用窗口的尺寸调整API完成变更。
import SwiftUI struct ContentView: View { @State private var originalSize: CGSize = .zero @State private var isExpanded = false private let expandedSize = CGSize(width: 800, height: 600) var body: some View { VStack { Button(isExpanded ? "恢复窗口尺寸" : "放大窗口") { guard let window = NSApplication.shared.windows.first else { return } if isExpanded { window.setContentSize(originalSize) } else { originalSize = window.contentSize window.setContentSize(expandedSize) } isExpanded.toggle() } .padding() Text(isExpanded ? "当前为放大状态" : "当前为原始状态") } .frame(minWidth: 400, minHeight: 300) .onAppear { originalSize = NSApplication.shared.windows.first?.contentSize ?? .zero } } }
代码说明
onAppear:视图加载时记录窗口初始尺寸,作为后续恢复的基准值。- 按钮点击事件:根据
isExpanded状态切换窗口尺寸,同时更新状态标记。 - 直接通过
NSApplication.shared.windows.first获取当前应用的主窗口(如果是多窗口应用,需根据实际情况定位目标窗口)。
AppKit 实现方式(基于NSWindowController)
对于使用AppKit的项目,可在窗口控制器中封装尺寸切换逻辑:
import Cocoa class MainWindowController: NSWindowController { private var originalWindowSize: CGSize = .zero private let expandedSize = CGSize(width: 800, height: 600) private var isExpanded = false override func windowDidLoad() { super.windowDidLoad() originalWindowSize = window?.contentSize ?? .zero } @IBAction func toggleWindowSize(_ sender: NSButton) { guard let window = self.window else { return } if isExpanded { window.setContentSize(originalWindowSize) } else { window.setContentSize(expandedSize) } isExpanded.toggle() sender.title = isExpanded ? "恢复尺寸" : "放大窗口" } }
使用说明
- 在Storyboard/XIB中创建按钮,将其点击事件绑定到
toggleWindowSize方法。 windowDidLoad中初始化原始尺寸,确保后续恢复操作有基准值。
进阶优化:添加平滑动画
如果需要更友好的过渡效果,可使用NSAnimationContext实现尺寸调整的平滑动画:
// SwiftUI中添加动画 Button(isExpanded ? "恢复窗口尺寸" : "放大窗口") { guard let window = NSApplication.shared.windows.first else { return } NSAnimationContext.runAnimationGroup { context in context.duration = 0.3 context.allowsImplicitAnimation = true if isExpanded { window.setContentSize(originalSize) } else { originalSize = window.contentSize window.setContentSize(expandedSize) } } isExpanded.toggle() }
// AppKit中添加动画 @IBAction func toggleWindowSize(_ sender: NSButton) { guard let window = self.window else { return } NSAnimationContext.runAnimationGroup { context in context.duration = 0.3 if isExpanded { window.animator().setContentSize(originalWindowSize) } else { window.animator().setContentSize(expandedSize) } } completionHandler: { [weak self] in self?.isExpanded.toggle() sender.title = self?.isExpanded ?? false ? "恢复尺寸" : "放大窗口" } }
内容的提问来源于stack exchange,提问作者Ammar Asmro
相关产品推荐
相关产品推荐

