SwiftUI

2023 年 9 月 24 日

SwiftUI 客製 macOS App 螢幕上方的選單列

已複製到剪貼板


使用 commandsReplaced(content:) 可以完全替換掉目前 Scene 的所有 command。

SwiftUI 和 macOS
SwiftUI 和 macOS

更換 macOS 預設的選單列

所有的 Scene type,如:WindowGroup、Window ⋯⋯ 都有預設的一組 command,這裡的 command 指的是 Mac 螢幕上方的選單列中的功能。只要對 Scene 使用 commandsReplaced(content:) 就可以把這些預設的 command 換成自己客製的選單列。

@main
struct Example: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }
        .commandsReplaced {
            CommandGroup(after: .pasteboard) {
                Section {
                    Button("Show Clipboard") {
                        // open window
                    }
                }
            }
        }
    }
}

這裡會移除所有預設的 command,並把「Show Clipboard」功能放在處理剪貼簿的選單列後方。

CommandGroup

在 commandsReplaced 裡,可以用 CommandGroup 加入一組功能列,CommandGroup 有三個 init:

// 把自訂 command 加在指定位置的後方
init(after: CommandGroupPlacement, addition: () -> Content)
// 把自訂 command 加在指定位置的前方
init(before: CommandGroupPlacement, addition: () -> Content)
// 用自訂 command 取代指定的位置
init(replacing: CommandGroupPlacement, addition: () -> Content)

這裡會發現,init CommandGroup 會需要給定 CommandGroupPlacement,而後面的 addition 就是我們想加入選單列的功能,用 Section 加 Button 就可以了。

CommandGroupPlacement

CommandGroupPlacement 是 Apple 定義的 command 標準位置,並不會顯示在 UI 上,想把自訂義功能加到什麼位置可以參考下方的整理。主要分成六大類:

App interactions:

預設 分類
appInfo About App App 資訊、使用者條款
appSettings Preferences 設定、偏好
systemServices Services submenu 系統服務
appVisibility Hide App、Hide Others、Show All 顯示、隱藏
appTermination Quit App 結束 App
SwiftUI 在 macOS 中,CommandGroupPlacement 為 App interactions 的位置
SwiftUI 在 macOS 中,CommandGroupPlacement 為 App interactions 的位置

File manipulation:

預設 分類
newItem New、Open、Open Recent submenu 新增、開啟別的檔案
saveItem Close、Save、Save As/Duplicate、Revert to Saved 儲存檔案、關閉視窗
importExport 輸入、輸出非 app 原生支援的檔案格式
printItem Page Setup、Print 列印內容
SwiftUI 在 macOS 中,CommandGroupPlacement 為 File manipulation 的位置
SwiftUI 在 macOS 中,CommandGroupPlacement 為 File manipulation 的位置

Content updates:

預設 分類
undoRedo Undo、Redo 還原、重做
pasteboard Cut、Copy、Paste、Paste and Match Style、Delete、Select All 剪貼簿相關
textEditing Find submenu、Spelling and Grammer submenu、Substitutions submenu、Transformations submenu、Speech submenu 處理、轉換文字
textFormatting Font submenu、Text submenu 處理、轉換文字風格
SwiftUI 在 macOS 中,CommandGroupPlacement 為 Content updates-Edit 的位置
SwiftUI 在 macOS 中,CommandGroupPlacement 為 Content updates-Edit 的位置
SwiftUI 在 macOS 中,CommandGroupPlacement 為 Content updates-Format 的位置
SwiftUI 在 macOS 中,CommandGroupPlacement 為 Content updates-Format 的位置

Bars:

預設 分類
toolbar Show/Hide Toolbar、Customize Toolbar 控制 toolbar
sidebar Show/Hide Sidebar、Enter/Exit Full Screen 控制 sidebar、全螢幕模式
SwiftUI 在 macOS 中,CommandGroupPlacement 為 Bars 的位置
SwiftUI 在 macOS 中,CommandGroupPlacement 為 Bars 的位置

Windows:

預設 分類
windowSize Minimize、Zoom 控制 window size
singleWindowList App 定義的視窗
windowList App 正開啟的視窗
windowArrangement Bring All to Front 控制 App 的 window
SwiftUI 在 macOS 中,CommandGroupPlacement 為 Windows 的位置

Help:

預設 分類
help App Help 文件、幫助資訊
SwiftUI 在 macOS 中,CommandGroupPlacement 為 Help 的位置
SwiftUI 在 macOS 中,CommandGroupPlacement 為 Help 的位置

討論

不過最後有個小地方要注意,因為 macOS 不會讓 App 自己名字的選單為空,也就是說,如果我們沒有任何 App interactions 的類別,那後方最靠近的功能就會遞補進來。舉例來說,我們不使用 App interactions 類別,那後面依序還有「File manipulation、Content updates、Bar、Windows、Help」,這時 File 選單列會消失,裡面的功能就會遞補進 App interactions。

macOS All CommandGroupPlacement without App interactions
SwiftUI 在 macOS 中,App interactions 類別為空時,會被後方的類別補上

分享文章

已複製到剪貼板

主題文章

查看 SwiftUI

超級感謝

關於 XcodeProject

XcodeProject 創立於 2023,致力於協助開發者探索 Apple 的創新世界,學習在 iOS、iPadOS、macOS、tvOS、visionOS 與 watchOS 上開發 App,發現眾多技術與框架,讓開發者獲得更多能力。


Contacts

Ricky Chuang

XcodeProject

RickyChuang.xcodeproj@gmail.com

XcodeProject 聯絡

contact.xcodeproj@gmail.com

最新文章