SwiftUI macOS菜单栏应用如何通过按钮修改NSPopover下拉窗口大小
问题原因
- 实例不匹配:你在ContentView中自行初始化的AppDelegate是全新实例,和系统启动时创建的全局唯一AppDelegate不是同一个对象,修改的是未挂载显示的popover,自然无效果。
- 属性变更未同步:AppDelegate作为ObservableObject,其popover属性未添加
@Published标记,修改时不会触发状态同步,系统无法感知变更。
解决步骤
- 调整AppDelegate代码:给popover属性添加
@Published标记,创建ContentView时将当前自身实例传入,避免ContentView自行初始化AppDelegate。 - 调整ContentView代码:接收外部传入的AppDelegate实例,修改尺寸时可加上系统动画保证变更生效。
修改后AppDelegate代码
@NSApplicationMain class AppDelegate: NSObject, NSApplicationDelegate, ObservableObject { // 新增@Published标记,属性变更时自动发布通知 @Published var popover = NSPopover.init() var statusBar: StatusBarController? func applicationDidFinishLaunching(_ aNotification: Notification) { // 创建ContentView时传入当前AppDelegate实例 let contentView = ContentView(app: self) popover.contentViewController = MainViewController() // 默认菜单栏窗口尺寸 popover.contentSize = NSSize(width: 360, height: 360 ) popover.contentViewController?.view = NSHostingView(rootView: contentView) statusBar = StatusBarController.init(popover) } func applicationWillTerminate(_ aNotification: Notification) { // 销毁逻辑 } }
修改后ContentView代码
struct ContentView: View { // 接收外部传入的AppDelegate实例,不自行初始化 @ObservedObject var app: AppDelegate var body: some View { VStack{ Text("Hello World") .padding(.top, 10) Button { biggerwindow() } label: { Image("tv") } } } func biggerwindow(){ // 加动画保证变更生效,也可以直接赋值app.popover.contentSize NSAnimationContext.runAnimationGroup { context in context.duration = 0.3 app.popover.animator().contentSize = NSSize(width: 800, height: 800) } } }
内容的提问来源于stack exchange,提问作者Eric
相关产品推荐
相关产品推荐

