macOS 27 與 iPadOS 27 的選單項目圖片會消失

在 macOS 27 上,只要您連結的是 macOS 27 SDK,一個只有圖片、沒有標題的選單項目就會渲染成一片空白。在更早的 SDK 上,Apple 替這種情況留了後路:當選單項目的標題與屬性標題皆為空時,系統會自動顯示圖片。1但只要改用 27 重新建置,這層保護就失效了。

macOS 27 與 iPadOS 27 預設隱藏大多數選單項目圖片,而消失的究竟是哪些,取決於您連結的是哪一個 SDK。Apple 把這個結果形容為「近似於 macOS 26.0 之前的行為」,換句話說:macOS 26 大範圍地為選單加上圖片,而 27 又把大部分收了回去。1

受影響的框架有三個,每一個的解除方式都不一樣。如果您搜尋過 preferredImageVisibility 又剛好寫的是 SwiftUI,那麼這個屬性對您而言並不存在。

快速摘要

對於連結 macOS 26.0 及後續 SDK 的 App,macOS 27 預設隱藏選單項目的符號圖片;若是連結 macOS 27 SDK 的 App,連非符號圖片也一併消失。12純圖示的選單項目在 27 之前的 SDK 上受到自動保護,而在以 27 重新建置後便失去這層保護。3iPadOS 27 預設隱藏設定於選單元素上的圖片。4AppKit 與 UIKit 提供 preferredImageVisibility,值有 .automatic、.visible 與 .hidden;SwiftUI 則改用 labelStyle(.titleAndIcon)。5「設定」、「分享」與「列印」在全系統範圍內保留各自的圖片,因此您會看到部分圖示仍在,進而誤以為自己的圖片壞了。

依 SDK 區分的實際變動

AppKit 的這項行為分散在三則發行說明條目中,其中兩則被歸類為問題修正,這也是各方對這項變動的說法彼此矛盾的原因。

連結對象 符號圖片 非符號圖片 純圖示項目
macOS 26 之前的 SDK 不受影響 不受影響 不受影響
macOS 26.0 至 26.x 隱藏 顯示 自動顯示
macOS 27 SDK 隱藏 隱藏 隱藏

基準的那一則條目指出,NSMenu 預設隱藏所有選單項目的符號圖片,非符號圖片則維持可見,且此變動適用於連結 macOS 26.0 及後續 SDK 的應用程式。1

第二則條目擴大了隱藏範圍:「對於連結 macOS 27 SDK 的應用程式,符號與非符號選單項目圖片現在都會自動隱藏。對於連結較早 SDK 的應用程式,非符號圖片仍會自動維持可見,以保留既有的應用程式行為。」2

第三則條目才是值得讀兩遍的那一則:3

「對於連結 macOS 27 之前 SDK 的應用程式,當選單項目的標題與屬性標題皆為空時,NSMenu 現在會自動顯示選單項目圖片。這在圖片是選單項目內容唯一呈現方式時,保留了既有的應用程式行為。而連結 macOS 27 SDK 時,這些圖片將自動隱藏;採用此種設計的選單應改用 preferredImageVisibility API,以確保選單項目圖片維持可見。」

Apple 為純圖示的選單項目架了一張安全網,接著又白紙黑字寫明:這張網不延伸到新的 SDK。凡是整個內容就是一張圖片的選單項目,重新建置後就會渲染成空白。您的原始碼一個字都沒改,觸發條件是您編譯時所依據的 SDK。

純圖示選單項目其實沒有聽起來那麼罕見。格式選單裡的色票,色塊本身就是選項;以頭像或狀態圖示區分每一列的裝置或帳號選擇器;以純圖片項目橫向排成一列的表情反應與 emoji 列;顯示檔案類型圖示、檔名另行渲染的最近文件清單。在這些情況下,圖片並不是掛在標籤旁的裝飾——圖片就是標籤。

這些選單會退化成一整欄空白的列,而且點擊依然有反應。選單保有原本的高度、分隔線與可點擊區域,因此在自動化檢測的眼中,它看起來根本不像渲染失敗。一個斷言「選單有六個項目」的 UI 測試照樣通過。截圖比對抓得到這件事,項目數量的斷言抓不到。

真正的家族相似之處在於它的安靜。macOS 27 也會在不詢問的情況下拒絕跨團隊容器存取——API 回傳一個看起來完全正常的 URL,失敗要等到實際讀取時才浮現。兩項變動都以沉默取代了原本可見的訊號,也都以「看起來不像它真正的樣子」的形式現身。

三種框架,三種修正

框架 API 值
AppKit NSMenuItem.preferredImageVisibility .automatic、.visible、.hidden
UIKit UIMenuElement.preferredImageVisibility .automatic、.visible、.hidden
SwiftUI labelStyle(.titleAndIcon) 一種標籤樣式,不是列舉

AppKit 與 UIKit 的形式一致。兩個屬性都接受 ImageVisibility 列舉,值為 .automatic、.visible 與 .hidden,兩者都以 NSInteger 實作 RawRepresentable,也都是 Sendable。67

// AppKit
menuItem.preferredImageVisibility = .visible

// UIKit — also available on the updated initializers
// for UIMenu, UIAction, UICommand, and UIKeyCommand
let action = UIAction(title: "Export", image: exportImage) { _ in export() }
action.preferredImageVisibility = .visible

SwiftUI 走的是另一條路。其發行說明寫道:「請搭配 .titleAndIcon 樣式使用 labelStyle(_:) 檢視修飾器,以表明選單項目 Label 的圖示應始終顯示。」5

Menu("File") {
    Button {
        openDocument()
    } label: {
        Label("Open Document", systemImage: "doc")
    }
    .labelStyle(.titleAndIcon)
}

另外請注意,SwiftUI 的預設值對齊的是 AppKit 的基準行為,而非 27 SDK 的行為:符號圖片隱藏,非符號圖片仍然可見。5上面那張 SDK 連結對照表描述的是 AppKit,別想當然耳地套到 SwiftUI 上。

影響範圍比聽起來窄

平台的措辭要細讀,因為各則條目的寫法並不相同。

UIKit 那一則涵蓋 iPadOS 27.0 與 macOS 27.0 上的「選單列與快捷選單」。4SwiftUI 那一則更具體:iPadOS 27.0 與 macOS 27.0 的選單列,「以及 macOS 27.0 上的快捷選單」。5iPadOS 上的 SwiftUI 快捷選單並未被點名。iOS 27.0 發行說明:棄用、破壞性變更與修正一文把 iPadOS 的選單變更歸為作業系統層級,影響 27.0 裝置上的每一個二進位檔。

UIMenuElement.preferredImageVisibility 在 iOS、iPadOS、Mac Catalyst、tvOS 與 visionOS 27.0 上皆可使用。7但 API 在某個平台上推出,不等於隱藏行為在那裡也已生效。Apple 的發行說明只描述了 iPadOS 與 macOS 的行為。tvOS 與 visionOS 應視為「未載明」,而非「已確認」。

Interface Builder 這一面

有一個細節沒有對應的程式碼寫法。對於從 xib 檔建立的選單項目,NSMenu 會參照選單項目檢閱器中的「macOS 26.0 only」核取方塊:未勾選則圖片維持可見,勾選則隱藏。1

Interface Builder 裡的一個屬性,如今會改變執行期的圖片可見性。如果您的選單來自 xib,這場稽核就不是一次程式碼搜尋能了事的,得有人親自打開檢閱器看。

為什麼有些圖示活了下來

AppKit 與 UIKit 都持續為「設定」、「分享」、「列印」這類全系統通用的選單項目提供預設可見的圖片。14SwiftUI 亦然。5

實際的後果是診斷上的混淆。您更新後打開選單,看到「設定」與「分享」旁邊有圖示,自家項目旁邊卻沒有。合理的推論是圖片載入失敗、資產目錄壞了,或是符號名稱寫錯了。但這些事一件都沒發生,系統只是在套用一套豁免少數知名項目的政策。

決定要保留哪些圖示

五則發行說明條目無一例外,都要開發者參閱更新後的 Human Interface Guidelines,據以決定哪些選單項目仍應顯示圖片。145這份指引究竟怎麼說,我無法驗證:HIG 的選單頁面採用用戶端渲染,抓取工具幾乎取不到任何文字,而且 HIG 內容也沒有像 API 參考文件那樣的 JSON 端點。請自己去確認,不要輕信任何摘要的說法——包括這一篇。

發行說明本身唯一提供的具體判準來自 SwiftUI 那一則:當選單項目「代表的是一個物件或一個概念,而非一項動作」時,建議顯示圖示。5

這條規則堪用。列出開啟中文件、可用裝置或已存篩選條件的選單,命名的是物件,圖示在那裡承載了辨識身分的功能。而動詞構成的選單——也就是絕大多數選單——每一列旁邊擺個圖示並不會多出什麼價值。Apple 顯然認定 macOS 26 把圖片用得太浮濫,而 27 就是那次修正。

以 27 SDK 出貨前該做的事

先找出純圖示的選單項目。它們壞得最徹底,因為圖片就是全部的內容。任何帶有圖片卻標題為空的 NSMenuItem,以及任何以相同方式建構的 UIMenu 元素,都必須明確設定 .visible。

逐項決定,不要一刀切。到處設定 .visible 等於推翻一次深思熟慮的平台變動,把自己送回 macOS 26 的原點。「物件對比動作」這條規則,是比全面覆寫更好的篩選器。

xib 要另外搜。「macOS 26.0 only」核取方塊沒辦法像屬性指派那樣用 grep 找出來,但它確實會改變行為。

如果兩個 SDK 世代都要支援,就兩邊都測。同一份原始碼,對 26 建置與對 27 建置的渲染結果並不相同。這讓截圖與 UI 測試變得與 SDK 綁定,而過去並非如此。Xcode 27 正式推出一文引用了 Apple 公布的 2027年4月期限,此後 iOS 與 iPadOS 的上傳都必須使用 27 SDK。

以 SDK 連結決定行為,正逐漸成為這一版反覆出現的樣態。iOS 27 的 canOpenURL 棄用也繞著同一根軸轉,而實務上的教訓一再重演:決定使用者看到什麼的,是您編譯期的選擇,而不是您的原始碼。可調整大小的 iPhone 時代一文在版面上呈現同一根軸:iOS 27 每一則與可調整大小相關的條目,都以 27 SDK 為條件。

要有發行說明還會再變的心理準備。三則 AppKit 條目中有兩則歸類為問題修正,這意味著這項行為在 beta 週期中已經改過一次。我在 2026年8月1日對照 Beta 4 的說明重新驗證過全部五則,內容與此處引述一致。在依據其中任何一項行動之前,請對照當前的說明再確認一次。macOS 27 發行說明:棄用、破壞性變更與修正一文引用了這些選單條目在正式版說明中的寫法。

稽核既有的程式碼庫

這項變動夠機械化,足以有系統地稽核,而且值得在重新建置之前就做,而不是等測試人員回報選單一片空白之後才做。

從最嚴重的情況開始查。帶有圖片卻標題為空的 NSMenuItem,是唯一會產生「看得出壞掉」而非「只是變樸素」的選單的失敗情況。在程式碼中,要找的是有圖片指派、卻沒有對應標題的地方:

# Menu items constructed with an image and no title argument
rg 'NSMenuItem\(' --type swift -A3 | rg -B1 'image ='
rg 'setImage|\.image\s*=' --type swift | rg -i 'menu'

這兩種樣式都不夠周全,因為標題可能三行之後才設定,也可能是從本地化字串表讀來的。請把結果當成待檢查的候選清單,而不是結論。

接著查 xib。「macOS 26.0 only」核取方塊沒有任何 grep 幫得上忙,它藏在選單項目檢閱器裡,而不在任何建置過程看得見的屬性中。如果您的選單出自 Interface Builder,稽核就意味著逐一打開每個選單、檢查每個項目。

再來是 UIKit 的選單建構器。UIMenu、UIAction、UICommand 與 UIKeyCommand 都新增了接受 preferredImageVisibility 的初始化器,因此修正可以直接寫在建構當下,不必事後再補上一行指派。4

然後是選單內的 SwiftUI Label 用法。這些最容易漏掉,因為選單裡的 Label 在原始碼中看起來和其他地方的 Label 一模一樣。修飾器要加在標籤上,而且只加在您希望保留圖示的地方。

建置兩次並比對。最可靠的檢查根本不必讀程式碼。分別對 26 SDK 與 27 SDK 建置,打開同一批選單,兩邊都拍下來。同一份原始碼產出兩種不同的選單,正是這項變動的重點所在,而並排比對找得到 grep 找不到的東西。

最後這一步同時保住了您的截圖。行銷圖片、說明文件與 App Store 素材裡出現的選單,都是在有人擷取的當下、以那時最新的 SDK 拍成的。如果它們顯示了您出貨版本已不再渲染的圖示,那它們現在就是錯的,而且建置流程中沒有任何一環會替您標記出來。

重點整理

給 AppKit 開發者: - 連結 macOS 27 SDK 也會隱藏非符號圖片,不只是符號。只稽核 SF Symbols 會漏掉一半。 - 純圖示選單項目在 27 SDK 上失去自動保護,會渲染成空白。請逐一設定 preferredImageVisibility = .visible。 - 在 xib 中定義的選單帶有「macOS 26.0 only」核取方塊,它會在任何程式碼路徑之外改變可見性。

給 UIKit 開發者: - preferredImageVisibility 位於 UIMenuElement 上,也出現在 UIMenu、UIAction、UICommand 與 UIKeyCommand 更新後的初始化器中。 - 這個屬性在 tvOS 與 visionOS 上存在,但 Apple 只替 iPadOS 與 macOS 記載了行為。先驗證,別直接假設。

給 SwiftUI 開發者: - preferredImageVisibility 不是您該用的 API。請在 Label 上使用 labelStyle(.titleAndIcon)。 - SwiftUI 的預設值隱藏符號圖片、保留非符號圖片,對齊的是 AppKit 的基準行為,而非 27 SDK 的行為。

常見問題

為什麼「設定」與「分享」還有圖示?

系統豁免了特定的通用選單項目。AppKit、UIKit 與 SwiftUI 都持續為「設定」、「分享」、「列印」這類項目提供預設可見的圖片。145看到那些圖示還在、自家的卻不見了,是預期中的行為,不是載入失敗。

停留在較舊的 SDK 就能避開嗎?

只能避開一部分,而這個區別很重要。連結 macOS 26.0 及後續 SDK 的 App 已經會隱藏符號圖片。1維持在 macOS 27 SDK 以下,可以保住非符號圖片的可見性,也保住純圖示項目的自動保護。23但這並不會讓符號圖片回來。

只有圖片、沒有標題的選單項目會怎樣?

在 macOS 27 之前的 SDK 上,由於標題與屬性標題皆為空,NSMenu 會自動顯示圖片。3在 macOS 27 SDK 上,這層保護不再適用,圖片會被隱藏,留下一個沒有任何可見內容的選單項目。請設定 preferredImageVisibility = .visible。

tvOS 與 visionOS 的情況一樣嗎?

UIMenuElement.preferredImageVisibility 在兩者的 27.0 上皆可使用。7但發行說明只描述了 iPadOS 與 macOS 的隱藏行為。API 存在於某個平台,並不足以證明該行為在那裡已經生效。

我該保留哪些圖示?

發行說明指向 Human Interface Guidelines,而我無法直接讀取該文件。Apple 在 SwiftUI 那一則中給出的判準是:當選單項目「代表的是一個物件或一個概念,而非一項動作」時顯示圖示。5

資料來源


  1. Apple,“macOS 27 Golden Gate Beta 4 Release Notes,” AppKit。Radar 170477566:NSMenu 預設隱藏所有選單項目符號圖片,非符號圖片維持可見;適用於連結 macOS 26.0 及後續 SDK 的應用程式;xib「macOS 26.0 only」核取方塊的行為;preferredImageVisibility 屬性;「設定」、「分享」與「列印」的預設可見圖片。機器可讀版本位於 developer.apple.com/tutorials/data/documentation/macos-release-notes/macos-27-release-notes.json。於 2026年8月1日重新驗證。 ↩↩↩↩↩↩↩↩↩

  2. Apple,macOS 27 Golden Gate Beta 4 Release Notes,AppKit,Resolved Issues。Radar 179374305(FB23070183):「對於連結 macOS 27 SDK 的應用程式,符號與非符號選單項目圖片現在都會自動隱藏。對於連結較早 SDK 的應用程式,非符號圖片仍會自動維持可見,以保留既有的應用程式行為。」 ↩↩↩

  3. Apple,macOS 27 Golden Gate Beta 4 Release Notes,AppKit,Resolved Issues。Radar 179936632:在 27 之前的 SDK 上,標題與屬性標題皆為空的選單項目會自動顯示圖片;以及連結 macOS 27 SDK 時該行為的移除。 ↩↩↩↩

  4. Apple,“iOS & iPadOS 27 Beta 4 Release Notes,” UIKit。Radar 170479084:iPadOS 27.0 與 macOS 27.0 上的選單列與快捷選單預設不顯示設定於選單元素上的圖片;UIMenuElement 上的 preferredImageVisibility,以及 UIMenu、UIAction、UICommand 與 UIKeyCommand 更新後的初始化器。同一則 Radar 亦出現於 macOS 27 的說明中。 ↩↩↩↩↩↩

  5. Apple,iOS & iPadOS 27 Beta 4 Release Notes,SwiftUI。Radar 170480710:SwiftUI 在多數情境下預設隱藏所有選單項目符號圖片,非符號圖片維持可見;labelStyle(_:) 搭配 .titleAndIcon;當選單項目「代表的是一個物件或一個概念,而非一項動作」時顯示圖示的建議;通用系統項目的預設可見圖片。 ↩↩↩↩↩↩↩↩↩

  6. Apple,“NSMenuItem.preferredImageVisibility” 與 “NSMenuItem.ImageVisibility.” 列舉值 .automatic、.visible、.hidden;以 NSInteger 實作 RawRepresentable;macOS 27.0 起可用。 ↩

  7. Apple,“UIMenuElement.preferredImageVisibility” 與 “UIMenuElement.ImageVisibility.” 列舉值 .automatic、.visible、.hidden;iOS 27.0、iPadOS 27.0、Mac Catalyst 27.0、tvOS 27.0、visionOS 27.0 起可用。 ↩↩↩

相關文章

開發者眼中的 Touch on Mac:36 點、手勢辨識器與 Sidecar

開發者視角的 Mac 觸控:觸控會轉成點按,手勢辨識器是取得直接觸控的唯一途徑,觸控目標 36 點,以 Sidecar 測試,以及 SDK 尚未補上的空缺。

21 分鐘閱讀

Touch on Mac 文件:遷移指南、遊戲技術說明與 HIG

Apple 的 Touch on Mac 文件在議程之後才登場:AppKit 遷移對照表、一份遊戲技術說明、排他視圖、兩個除錯用預設值,以及 Human Interface Guidelines 的規則。

28 分鐘閱讀

為 iPhone Duo 做設計:什麼會移動、什麼會分割、什麼保持不動

把 Apple 的 iPhone Duo 設計指南與三場 Tech Talk 當成規則來讀:以兩個尺寸類別取代逐一適配的姿勢、摺痕處的位移、arrangement,以及側邊列。

18 分鐘閱讀