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

如何在macOS中监听visibleFrame变化(无需定时器)

解决macOS调整Dock大小时实时更新visibleFrame的问题

你的代码目前无法在Dock尺寸变化时自动更新visibleFrame,原因是NSScreen.main?.visibleFrame的变化不会主动通知SwiftUI视图。可以通过监听系统通知的方式实现实时更新,无需定时器轮询,修改后的代码如下:

import SwiftUI

struct ContentView: View {
    @StateObject var myScreen: MyScreen = MyScreen.shared
    
    var body: some View {
        if let size = myScreen.visibleFrame?.size {
            Text("visibleFrame size: \(size)")
        }
    }
}

class MyScreen: ObservableObject {
    static let shared = MyScreen()
    
    @Published var visibleFrame: NSRect?
    
    private var notificationObserver: NSObjectProtocol?
    
    private init() {
        // 初始化时获取初始值
        visibleFrame = NSScreen.main?.visibleFrame
        
        // 监听屏幕参数变化通知
        notificationObserver = NotificationCenter.default.addObserver(
            forName: NSApplication.didChangeScreenParametersNotification,
            object: nil,
            queue: .main
        ) { [weak self] _ in
            self?.visibleFrame = NSScreen.main?.visibleFrame
        }
    }
    
    deinit {
        // 移除通知观察者,避免内存泄漏
        if let observer = notificationObserver {
            NotificationCenter.default.removeObserver(observer)
        }
    }
}

关键说明:

  • @Published属性:将visibleFrame标记为@Published,SwiftUI会自动监听该属性的变化,触发视图刷新。
  • 系统通知监听:NSApplication.didChangeScreenParametersNotification会在屏幕配置发生变化时触发(包括Dock大小调整、分辨率变更等场景)。
  • 内存管理:在deinit方法中移除通知观察者,防止内存泄漏。

内容的提问来源于stack exchange,提问作者swiftPunk

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 14:28:13