You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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 ? "恢复尺寸" : "放大窗口"
    }
}

使用说明

  1. 在Storyboard/XIB中创建按钮,将其点击事件绑定到toggleWindowSize方法。
  2. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 10:20:39