如何在点击MenuBarExtra按钮或按快捷键时显示悬浮面板?
在SwiftUI菜单栏应用中实现悬浮面板(Floating Panel)
针对你的需求,我们可以通过手动管理自定义FloatingPanel实例的方式,实现点击菜单按钮或快捷键显示悬浮面板的功能,具体修改如下:
1. 修改主App结构体
更新uCopyApp.swift代码,添加面板实例管理、显示逻辑和快捷键支持:
import SwiftUI @main struct uCopyApp: App { @State private var showingPanel = false @State private var floatingPanel: FloatingPanel<ContentView>? var body: some Scene { MenuBarExtra("MenuBar", systemImage: "line.diagonal") { Button("显示悬浮面板") { toggleFloatingPanel() } Button("退出") { NSApplication.shared.terminate(nil) } } .commands { CommandGroup(after: .appVisibility) { Button("切换悬浮面板") { toggleFloatingPanel() } .keyboardShortcut("P", modifiers: [.command, .option]) // 自定义快捷键 } } } private func toggleFloatingPanel() { if let panel = floatingPanel { // 已有面板实例,切换显示/隐藏状态 if panel.isVisible { panel.close() } else { panel.makeKeyAndOrderFront(nil) } } else { // 创建新的面板实例,设置初始尺寸 let contentRect = NSRect(x: 0, y: 0, width: 300, height: 400) let panel = FloatingPanel( view: { ContentView() }, contentRect: contentRect, isPresented: $showingPanel ) panel.center() // 让面板居中显示 panel.makeKeyAndOrderFront(nil) // 激活面板 floatingPanel = panel } showingPanel.toggle() } } // 替换为你的实际面板内容视图 struct ContentView: View { var body: some View { VStack(spacing: 20) { Text("悬浮面板内容") .font(.title) Text("点击外部区域自动关闭") .font(.caption) .foregroundColor(.secondary) Spacer() } .padding() .background(Color.white) } }
2. 关键逻辑说明
- 面板实例管理:用
@State private var floatingPanel: FloatingPanel<ContentView>?存储面板实例,避免重复创建,保证用户每次操作的是同一个面板。 - 显示/隐藏切换:
toggleFloatingPanel()方法会判断面板是否存在,存在则切换显示状态,不存在则创建新面板并显示。 - 快捷键支持:通过
.commands修饰符添加全局快捷键,用户可以通过快捷键快速唤起/隐藏面板。 - 状态同步:自定义的
FloatingPanel会在关闭时自动更新isPresented绑定值,确保App的状态和面板实际状态一致。
3. 保持现有FloatingPanel代码不变
你已经实现的FloatingPanel.swift代码无需修改,它的逻辑(失去焦点自动关闭、可移动、样式设置等)可以正常工作。
内容的提问来源于stack exchange,提问作者FaiChou
相关产品推荐
相关产品推荐

