Zum Inhalt springen

.labelStyle(.iconOnly) statt Image in Button verschachteln

Das richtige SwiftUI-Pattern für Icon-only Buttons, das die Barrierefreiheit bewahrt, ohne die Lesbarkeit zu opfern.

Hör auf, gegen das Framework zu kämpfen

Ein Pattern, das ich ständig in SwiftUI-Code sehe, ist das manuelle Erstellen von Icon-only Buttons, indem ein Image direkt in die Label-Closure eines Button gepackt wird. Es funktioniert visuell, wirft aber Barrierefreiheits-Informationen weg und arbeitet gegen das Design von SwiftUI.

Der falsche Weg

Button {
   toggleSidebar()
} label: {
   Image(systemName: "sidebar.left")
}

Das rendert ein tippbares Icon, aber VoiceOver hat kein aussagekräftiges Label zum Vorlesen. Der Nutzer hört etwas wie „button” oder den rohen SF Symbol-Namen, was nicht hilfreich ist.

Der richtige Weg

Button("Toggle Sidebar", systemImage: "sidebar.left") {
   toggleSidebar()
}
.labelStyle(.iconOnly)

Oder mit explizitem Label:

Button(action: toggleSidebar) {
   Label("Toggle Sidebar", systemImage: "sidebar.left")
}
.labelStyle(.iconOnly)

Code comparison showing the wrong way versus the right way

Warum das wichtig ist

Die Label-View trägt sowohl einen Titel als auch ein Icon. Wenn du .labelStyle(.iconOnly) anwendest, versteckt SwiftUI den Titel visuell, bewahrt ihn aber im Accessibility-Baum. VoiceOver liest „Toggle Sidebar, button” vor – genau das, was der Nutzer hören muss.

Dieses Pattern macht deinen Code auch anpassungsfähiger. Wenn du dich später entscheidest, Text neben dem Icon anzuzeigen (zum Beispiel in einer Toolbar auf dem iPad), änderst du einfach den Label-Style auf .titleAndIcon. Keine Umstrukturierung nötig.

Über Buttons hinaus

Dasselbe Prinzip gilt für jede View, die ein Label akzeptiert: NavigationLink, Toggle, Picker, Menüeinträge. Wann immer du versucht bist, ein nacktes Image zu verwenden, frag dich, ob ein Label mit einem Style-Modifier nicht passender wäre. In fast jedem Fall ist es das.

War das hilfreich? Folge mir auf Bluesky und Mastodon für mehr Swift-Tipps und Indie-Dev-Updates.