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

如何在点击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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 14:30:59