Les images des éléments de menu disparaissent dans macOS 27 et iPadOS 27
Un élément de menu doté d’une image mais sans titre n’affiche rien du tout dans macOS 27 si vous liez votre application au SDK de macOS 27. Sur les SDK antérieurs, Apple protège ce cas de figure en affichant automatiquement l’image dès lors que le titre et le titre attribué d’un élément de menu sont tous deux vides.1 Recompilez avec le 27 et la protection cesse de s’appliquer.
macOS 27 et iPadOS 27 masquent par défaut la plupart des images des éléments de menu, et ce qui disparaît dépend du SDK auquel vous avez lié votre application. Apple qualifie le résultat de « similaire au comportement antérieur à macOS 26.0 » : autrement dit, macOS 26 avait généralisé les images de menu, et le 27 les reprend en grande partie.1
Trois frameworks sont concernés, chacun avec son propre mécanisme de dérogation. Si vous avez cherché preferredImageVisibility et que vous écrivez du SwiftUI, sachez que cette propriété n’existe pas pour vous.
L’essentiel
macOS 27 masque par défaut les images symboliques des éléments de menu pour les applications liées à macOS 26.0 ou ultérieur ; celles liées au SDK de macOS 27 perdent en plus leurs images non symboliques.12 Les éléments de menu réduits à une icône sont automatiquement protégés sur les SDK antérieurs au 27 et perdent cette protection après recompilation avec le 27.3 iPadOS 27 masque par défaut les images définies sur les éléments de menu.4 AppKit et UIKit exposent preferredImageVisibility avec .automatic, .visible et .hidden ; SwiftUI passe plutôt par labelStyle(.titleAndIcon).5 Réglages, Partager et Imprimer conservent leurs images à l’échelle du système : vous verrez donc certaines icônes et pourrez en conclure à tort que les vôtres sont cassées.
Ce qui change réellement, selon le SDK
Le comportement d’AppKit est réparti sur trois entrées distinctes des notes de version, dont deux classées comme corrections. D’où les résumés contradictoires qui circulent sur ce changement.
| Édition de liens | Images symboliques | Images non symboliques | Éléments réduits à une icône |
|---|---|---|---|
| SDK antérieur à macOS 26 | inchangées | inchangées | inchangés |
| macOS 26.0 à 26.x | masquées | visibles | affichés automatiquement |
| SDK macOS 27 | masquées | masquées | masqués |
L’entrée de référence indique que NSMenu masque par défaut toutes les images symboliques des éléments de menu tandis que les images non symboliques restent visibles, et que le changement s’applique aux applications liées à macOS 26.0 ou ultérieur.1
Une deuxième entrée étend ce masquage : « Pour les applications liées au SDK de macOS 27, les images symboliques comme non symboliques des éléments de menu sont désormais masquées automatiquement. Pour les applications liées à des SDK antérieurs, les images non symboliques restent visibles automatiquement, ce qui préserve le comportement des applications existantes. »2
La troisième entrée mérite une seconde lecture :3
« Pour les applications liées à des SDK antérieurs à macOS 27, NSMenu affiche désormais automatiquement les images des éléments de menu lorsque le titre et le titre attribué de l’élément sont tous deux vides. Cela préserve le comportement des applications existantes lorsque l’image constitue l’unique représentation du contenu de l’élément de menu. Lors de l’édition de liens avec le SDK de macOS 27, ces images seront automatiquement masquées ; un menu conçu de cette manière doit recourir à l’API
preferredImageVisibilitypour garantir que les images de ses éléments restent visibles. »
Apple a construit un filet de sécurité pour les éléments de menu réduits à une icône, puis a documenté le fait que ce filet ne s’étend pas au nouveau SDK. Un élément de menu dont tout le contenu tient dans une image s’affiche vide après recompilation. Rien ne change dans votre code source. Le déclencheur, c’est le SDK avec lequel vous avez compilé.
Les éléments de menu réduits à une icône sont moins exotiques qu’il n’y paraît. Les échantillons de couleur d’un menu de mise en forme, où l’échantillon constitue lui-même le choix proposé. Les sélecteurs d’appareils ou de comptes qui identifient chaque entrée par un avatar ou un glyphe d’état. Les rangées de réactions et d’emojis construites comme une bande horizontale d’éléments uniquement composés d’images. Les listes de documents récents qui affichent une icône de type de fichier avec le nom rendu séparément. Dans chacun de ces cas, l’image n’est pas un ornement accolé à un libellé : elle est le libellé.
Ces menus se dégradent en une colonne de lignes vides qui répondent toujours aux clics. Le menu conserve sa hauteur, ses séparateurs et ses zones cliquables, si bien qu’un œil automatisé n’y verra pas un défaut de rendu. Un test d’UI qui vérifie qu’un menu compte six éléments continue de passer. Une comparaison de captures d’écran le détecte ; une assertion sur le nombre d’éléments, non.
C’est la discrétion du symptôme qui crée l’air de famille. macOS 27 refuse aussi l’accès aux conteneurs d’une autre équipe sans rien demander : là encore, l’API renvoie une URL d’apparence valide et l’échec attend la lecture. Les deux changements remplacent un signal visible par du silence, et tous deux se manifestent sous les traits d’autre chose.
Trois frameworks, trois correctifs
| Framework | API | Valeurs |
|---|---|---|
| AppKit | NSMenuItem.preferredImageVisibility |
.automatic, .visible, .hidden |
| UIKit | UIMenuElement.preferredImageVisibility |
.automatic, .visible, .hidden |
| SwiftUI | labelStyle(.titleAndIcon) |
un style de libellé, pas une énumération |
AppKit et UIKit partagent la même forme. Les deux propriétés acceptent une énumération ImageVisibility avec .automatic, .visible et .hidden, toutes deux RawRepresentable sur NSInteger, toutes deux 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 emprunte une autre voie. Sa note de version invite à « utiliser le modificateur de vue labelStyle(_:) avec le style .titleAndIcon pour indiquer que l’icône du Label d’un élément de menu doit toujours être affichée ».5
Menu("File") {
Button {
openDocument()
} label: {
Label("Open Document", systemImage: "doc")
}
.labelStyle(.titleAndIcon)
}
Notez également que le comportement par défaut de SwiftUI correspond à la référence AppKit et non à celle du SDK 27 : images symboliques masquées, images non symboliques toujours visibles.5 Le tableau ci-dessus sur l’édition de liens décrit AppKit. Ne présumez pas qu’il se transpose.
La portée est plus étroite qu’il n’y paraît
Lisez attentivement la formulation propre à chaque plateforme, car les entrées diffèrent.
L’entrée UIKit couvre « la barre de menus et les menus contextuels » sur iPadOS 27.0 et macOS 27.0.4 L’entrée SwiftUI est plus précise : la barre de menus sur iPadOS 27.0 et macOS 27.0, « ainsi que les menus contextuels sur macOS 27.0 ».5 Les menus contextuels SwiftUI sur iPadOS ne sont pas mentionnés.
UIMenuElement.preferredImageVisibility est disponible sur iOS, iPadOS, Mac Catalyst, tvOS et visionOS 27.0.7 Le fait que l’API soit livrée sur une plateforme ne signifie pas que le comportement de masquage y est actif. Les notes de version d’Apple décrivent le comportement pour iPadOS et macOS. Considérez tvOS et visionOS comme des cas non précisés plutôt que confirmés.
Le cas d’Interface Builder
Un détail n’a aucun équivalent en code. Pour les éléments de menu créés depuis un fichier xib, NSMenu tient compte d’une case à cocher « macOS 26.0 only » dans l’inspecteur d’élément de menu : décochée, elle laisse l’image visible ; cochée, elle la masque.1
Une propriété d’Interface Builder modifie désormais la visibilité des images à l’exécution. Si vos menus proviennent de xibs, l’audit ne se résume pas à une recherche dans le code. Il faut ouvrir l’inspecteur.
Pourquoi certaines icônes survivent
AppKit comme UIKit continuent de fournir des images visibles par défaut pour les éléments de menu courants à l’échelle du système, tels que Réglages, Partager et Imprimer.14 SwiftUI fait de même.5
L’effet concret, c’est une confusion au moment du diagnostic. Vous mettez à jour, vous ouvrez un menu, et vous voyez des icônes à côté de Réglages et Partager mais pas à côté de vos propres éléments. La conclusion la plus naturelle est que vos images ne se chargent plus, que votre catalogue de ressources est corrompu ou que les noms de symboles sont erronés. Il n’en est rien. Le système applique simplement une règle qui exempte une poignée d’éléments bien connus.
Choisir les icônes à conserver
Les cinq entrées des notes de version renvoient les développeurs aux Human Interface Guidelines mises à jour pour déterminer quels éléments de menu doivent encore afficher une image.145 Je n’ai pas pu vérifier ce que dit cette recommandation : la page des menus des HIG s’affiche côté client et ne renvoie presque aucun texte à un outil de récupération, et il n’existe pas de point d’accès JSON pour le contenu des HIG comme il en existe un pour la documentation d’API. Allez la consulter vous-même plutôt que de vous fier à un résumé, celui-ci compris.
La seule heuristique concrète que contiennent les notes de version elles-mêmes vient de l’entrée SwiftUI, qui suggère d’afficher l’icône lorsqu’un élément de menu « représente un objet ou un concept plutôt qu’une action ».5
La règle est exploitable. Un menu qui liste des documents ouverts, des appareils disponibles ou des filtres enregistrés nomme des objets, et l’icône y porte une identité. Un menu de verbes — c’est-à-dire la plupart des menus — ne gagne pas grand-chose à coller une icône devant chaque entrée. Apple semble avoir conclu que macOS 26 avait abusé des images, et le 27 est la correction.
À faire avant de livrer avec le SDK 27
Repérez d’abord vos éléments de menu réduits à une icône. Ce sont eux qui cassent le plus violemment, puisque l’image constitue tout le contenu. Tout NSMenuItem doté d’une image et d’un titre vide, ainsi que tout élément UIMenu construit de la même façon, doit recevoir explicitement .visible.
Décidez élément par élément, pas globalement. Passer partout à .visible revient à annuler un choix délibéré de la plateforme et à vous ramener là où macOS 26 se trouvait. La distinction objet/action fait un meilleur filtre qu’une dérogation générale.
Auditez les xibs séparément. La case « macOS 26.0 only » ne se repère pas par une recherche textuelle comme le ferait une affectation de propriété, et elle modifie le comportement.
Testez sur les deux générations de SDK si vous les prenez en charge. Une compilation avec le 26 et une compilation avec le 27 produisent des rendus différents à partir d’un code source identique. Vos captures d’écran et vos tests d’UI deviennent donc dépendants du SDK, ce qui n’était pas le cas auparavant.
Le fait que l’édition de liens détermine le comportement devient une constante de cette version. La dépréciation de canOpenURL dans iOS 27 pivote sur le même axe, et la leçon pratique se répète : c’est votre choix à la compilation, et non votre code source, qui détermine ce que voient les utilisateurs.
Attendez-vous à ce que les notes de version évoluent. Deux des trois entrées AppKit sont classées comme corrections, ce qui signifie que le comportement a déjà changé une fois pendant le cycle des bêtas. J’ai revérifié les cinq entrées dans les notes de la bêta 4 le 1er août 2026 et elles se lisent telles que citées ici. Vérifiez dans les notes en vigueur avant d’agir sur quoi que ce soit.
Auditer une base de code existante
Le changement est assez mécanique pour être audité méthodiquement, et il vaut mieux le faire avant la recompilation qu’après qu’un testeur a signalé un menu vide.
Commencez par le cas le plus grave. Un NSMenuItem porteur d’une image et d’un titre vide est le seul défaut qui produit un menu visiblement cassé plutôt que simplement plus dépouillé. Dans le code, cherchez une affectation d’image sans titre correspondant :
# 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'
Aucun de ces motifs n’est exhaustif, car un titre peut être défini trois lignes plus loin ou lu depuis une table de localisation. Traitez les résultats comme une liste de candidats à inspecter, pas comme un constat.
Passez ensuite aux xibs. Aucune recherche textuelle n’aide face à la case « macOS 26.0 only », qui vit dans l’inspecteur d’élément de menu et non dans un attribut visible par votre compilation. Si vos menus viennent d’Interface Builder, l’audit consiste à ouvrir chaque menu et à vérifier chaque élément.
Puis les constructeurs de menus UIKit. UIMenu, UIAction, UICommand et UIKeyCommand ont tous reçu des initialiseurs mis à jour acceptant preferredImageVisibility, si bien que le correctif peut se placer à la construction plutôt que dans une affectation ultérieure.4
Puis les Label SwiftUI utilisés dans les menus. Ce sont les plus faciles à laisser passer, parce qu’un Label dans un menu est identique, dans le code, à un Label placé n’importe où ailleurs. Le modificateur se pose sur le libellé, et uniquement là où vous voulez conserver l’icône.
Compilez deux fois et comparez. La vérification la plus fiable ne demande aucune lecture de code. Compilez avec le SDK 26 puis avec le SDK 27, ouvrez les mêmes menus et photographiez les deux. Un code source identique produisant deux menus différents, c’est tout l’enjeu de ce changement, et une comparaison côte à côte trouve ce qu’une recherche textuelle laissera passer.
Cette dernière étape protège aussi vos captures d’écran. Les images marketing, la documentation et les visuels de l’App Store qui montrent des menus ont été capturés avec le SDK en vigueur au moment où quelqu’un les a pris. S’ils montrent des icônes que la version que vous livrez n’affiche plus, ils sont désormais faux, et rien dans votre chaîne de compilation ne le signalera.
À retenir
Pour les développeurs AppKit :
- L’édition de liens avec le SDK de macOS 27 masque aussi les images non symboliques, pas seulement les symboles. N’auditer que vos SF Symbols, c’est en manquer la moitié.
- Les éléments de menu réduits à une icône perdent leur protection automatique sur le SDK 27 et s’affichent vides. Définissez preferredImageVisibility = .visible sur chacun d’eux.
- Les menus définis dans des xibs comportent une case « macOS 26.0 only » qui modifie la visibilité en dehors de tout chemin de code.
Pour les développeurs UIKit :
- preferredImageVisibility se trouve sur UIMenuElement ainsi que sur les initialiseurs mis à jour de UIMenu, UIAction, UICommand et UIKeyCommand.
- La propriété existe sur tvOS et visionOS, mais Apple documente le comportement pour iPadOS et macOS. Vérifiez avant de présumer.
Pour les développeurs SwiftUI :
- preferredImageVisibility n’est pas votre API. Utilisez labelStyle(.titleAndIcon) sur le Label.
- Par défaut, SwiftUI masque les images symboliques et conserve les images non symboliques, ce qui correspond à la référence AppKit et non au comportement du SDK 27.
FAQ
Pourquoi Réglages et Partager affichent-ils encore des icônes ?
Le système exempte certains éléments de menu courants. AppKit, UIKit et SwiftUI continuent tous de fournir des images visibles par défaut pour des éléments tels que Réglages, Partager et Imprimer.145 Voir ces icônes alors que les vôtres sont masquées est le comportement attendu, pas un défaut de chargement.
Rester sur un SDK antérieur permet-il d’y échapper ?
En partie, et la nuance compte. Les applications liées à macOS 26.0 ou ultérieur masquent déjà les images symboliques.1 Rester en deçà du SDK de macOS 27 préserve la visibilité des images non symboliques et conserve la protection automatique des éléments réduits à une icône.23 Cela ne restaure pas les images symboliques pour autant.
Qu’advient-il d’un élément de menu qui n’a qu’une image et aucun titre ?
Sur les SDK antérieurs à macOS 27, NSMenu affiche l’image automatiquement parce que le titre et le titre attribué sont tous deux vides.3 Avec le SDK de macOS 27, cette protection ne s’applique plus et l’image est masquée, ce qui laisse un élément de menu sans aucun contenu visible. Définissez preferredImageVisibility = .visible.
Est-ce identique sur tvOS et visionOS ?
UIMenuElement.preferredImageVisibility est disponible sur les deux à partir de la version 27.0.7 Les entrées des notes de version décrivent le comportement de masquage pour iPadOS et macOS. L’existence de l’API sur une plateforme ne confirme pas que le comportement y est actif.
Quelles icônes dois-je conserver ?
Les notes de version renvoient aux Human Interface Guidelines, que je n’ai pas pu consulter directement. L’heuristique énoncée par Apple dans l’entrée SwiftUI consiste à afficher une icône lorsque l’élément de menu « représente un objet ou un concept plutôt qu’une action ».5
Sources
-
Apple, “macOS 27 Golden Gate Beta 4 Release Notes,” AppKit. Radar 170477566 :
NSMenumasque par défaut toutes les images symboliques des éléments de menu tandis que les images non symboliques restent visibles ; s’applique aux applications liées à macOS 26.0 et ultérieur ; comportement de la case « macOS 26.0 only » dans les xibs ; propriétépreferredImageVisibility; images visibles par défaut pour Réglages, Partager et Imprimer. Copie exploitable par machine à l’adressedeveloper.apple.com/tutorials/data/documentation/macos-release-notes/macos-27-release-notes.json. Revérifié le 1er août 2026. ↩↩↩↩↩↩↩↩↩ -
Apple, macOS 27 Golden Gate Beta 4 Release Notes, AppKit, Resolved Issues. Radar 179374305 (FB23070183) : « Pour les applications liées au SDK de macOS 27, les images symboliques comme non symboliques des éléments de menu sont désormais masquées automatiquement. Pour les applications liées à des SDK antérieurs, les images non symboliques restent visibles automatiquement, ce qui préserve le comportement des applications existantes. » ↩↩↩
-
Apple, macOS 27 Golden Gate Beta 4 Release Notes, AppKit, Resolved Issues. Radar 179936632 : affichage automatique de l’image pour les éléments de menu dont le titre et le titre attribué sont tous deux vides sur les SDK antérieurs au 27, et suppression de ce comportement lors de l’édition de liens avec le SDK de macOS 27. ↩↩↩↩
-
Apple, “iOS & iPadOS 27 Beta 4 Release Notes,” UIKit. Radar 170479084 : la barre de menus et les menus contextuels sur iPadOS 27.0 et macOS 27.0 n’affichent pas par défaut les images définies sur les éléments de menu ;
preferredImageVisibilitysurUIMenuElementet initialiseurs mis à jour pourUIMenu,UIAction,UICommandetUIKeyCommand. Le même radar figure dans les notes de macOS 27. ↩↩↩↩↩↩ -
Apple, iOS & iPadOS 27 Beta 4 Release Notes, SwiftUI. Radar 170480710 : SwiftUI masque par défaut toutes les images symboliques des éléments de menu dans la plupart des contextes tandis que les images non symboliques restent visibles ;
labelStyle(_:)avec.titleAndIcon; recommandation d’afficher une icône lorsqu’un élément de menu « représente un objet ou un concept plutôt qu’une action » ; images visibles par défaut pour les éléments système courants. ↩↩↩↩↩↩↩↩↩ -
Apple, “NSMenuItem.preferredImageVisibility” et “NSMenuItem.ImageVisibility.” Cas
.automatic,.visible,.hidden;RawRepresentablesurNSInteger; disponible à partir de macOS 27.0. ↩ -
Apple, “UIMenuElement.preferredImageVisibility” et “UIMenuElement.ImageVisibility.” Cas
.automatic,.visible,.hidden; disponible sur iOS 27.0, iPadOS 27.0, Mac Catalyst 27.0, tvOS 27.0, visionOS 27.0. ↩↩↩