Mac: näher am iPad — Schrift, Seitenleiste, Formulare

Drei Gründe, warum der Mac anders aussah, und keiner davon war Geschmack.

**Die Schrift.** macOS rendert dieselben Textstile deutlich kleiner als iOS:
`largeTitle` misst dort 26 Punkt statt 34, Fließtext 13 statt 17. Eine
Oberfläche, die auf dem iPad stimmt, wirkt damit zusammengeschrumpft. Auf dem
Mac stehen jetzt feste Größen — die von iOS. Das kostet dort Dynamic Type;
vertretbar, weil macOS keine systemweite Textgröße kennt und man ein Fenster
stattdessen größer ziehen kann.

**Der Aufmacher wächst mit.** Das war der zweite, größere Teil: das Bild ist so
breit wie das Fenster, die Schrift darauf war es nicht. Bei 1280 Punkt Breite
wirkt ein 34-Punkt-Titel verloren, bei 834 auf dem iPad genau richtig. Titel,
Schriftzug, Angaben und Abstände richten sich jetzt nach der Breite des
Aufmachers — mit dem iPad als Bezug und einem Deckel, damit ein Fenster über
die ganze Wand nicht in Plakatschrift endet. Die Beschreibung bekommt
außerdem eine Zeilenbreite: ein Satz über 1280 Punkt ist unlesbar, das Auge
verliert die Zeile.

**Die Seitenleiste.** Sie richtet sich nach ihrem Inhalt, und bei Wörtern wie
„Start" fällt sie auf eine Breite zusammen, in der schon der Kontoname darunter
nicht mehr Platz hatte — daher das „S…". Die Beschriftungen haben jetzt eine
Mindestbreite.

**Die Formulare.** Auf dem Mac nahm SwiftUI den Spalten-Stil: Beschriftungen
rechts ausgerichtet, keine abgesetzten Abschnitte. Jetzt derselbe gruppierte
Stil wie auf iOS.

Dazu: Scrollbalken sind weg. Der graue Streifen unter dem Aufmacher kam daher,
dass in den Systemeinstellungen „Scrollbalken immer einblenden" steht —
dagegen reicht `.hidden` nicht, `.never` schon. Und das Fenster öffnet mit
1280 × 820 statt in Notizzettelgröße, ohne graue Titelleiste.

263 Tests grün, iOS baut unverändert.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Scarriffle
2026-09-13 15:59:22 +02:00
co-authored by Claude Opus 5
parent d54954b9c2
commit f8ada44a8c
21 changed files with 174 additions and 56 deletions
+40 -18
View File
@@ -187,11 +187,11 @@ struct RootView: View {
TabSection {
ForEach(session.libraries) { library in
Tab(
library.title,
systemImage: symbol(for: library.kind),
value: SidebarDestination.library(key: library.id, title: library.title)
) {
mediaStack { LibraryView(library: library) }
} label: {
tabLabel(library.title, symbol: symbol(for: library.kind))
}
.customizationID("flixy.tab.library.\(library.id)")
}
@@ -201,37 +201,33 @@ struct RootView: View {
.customizationID("flixy.tab.libraries")
if session.supportsLiveTV {
Tab(
"sidebar.liveTV",
systemImage: "dot.radiowaves.left.and.right",
value: SidebarDestination.liveTV
) {
Tab(value: SidebarDestination.liveTV) {
mediaStack { LiveTVView() }
} label: {
tabLabel("sidebar.liveTV", symbol: "dot.radiowaves.left.and.right")
}
.customizationID("flixy.tab.liveTV")
}
} else {
Tab(
"sidebar.library",
systemImage: "books.vertical",
value: SidebarDestination.libraryHub
) {
Tab(value: SidebarDestination.libraryHub) {
mediaStack { LibraryHubView() }
} label: {
tabLabel("sidebar.library", symbol: "books.vertical")
}
.customizationID("flixy.tab.libraryHub")
}
Tab(
"sidebar.downloads",
systemImage: "arrow.down.circle",
value: SidebarDestination.downloads
) {
Tab(value: SidebarDestination.downloads) {
mediaStack { DownloadsView() }
} label: {
tabLabel("sidebar.downloads", symbol: "arrow.down.circle")
}
.customizationID("flixy.tab.downloads")
Tab("sidebar.settings", systemImage: "gearshape", value: SidebarDestination.settings) {
Tab(value: SidebarDestination.settings) {
mediaStack { SettingsView() }
} label: {
tabLabel("sidebar.settings", symbol: "gearshape")
}
.customizationID("flixy.tab.settings")
@@ -274,6 +270,32 @@ struct RootView: View {
}
}
/// Die Beschriftung eines Eintrags.
///
/// Auf dem Mac mit einer Mindestbreite. Die Seitenleiste richtet sich nach
/// ihrem Inhalt, und bei kurzen Wörtern wie „Start" fällt sie auf eine
/// Breite zusammen, in der schon der Kontoname darunter nicht mehr Platz
/// hat — auf dem iPad ist sie dreimal so breit, und genau dieser
/// Unterschied macht die beiden Oberflächen ungleich.
private func tabLabel(_ title: LocalizedStringKey, symbol: String) -> some View {
let label = Label(title, systemImage: symbol)
#if os(macOS)
return label.frame(minWidth: 170, alignment: .leading)
#else
return label
#endif
}
/// Dieselbe Beschriftung, wenn der Titel erst vom Server kommt.
private func tabLabel(_ title: String, symbol: String) -> some View {
let label = Label(title, systemImage: symbol)
#if os(macOS)
return label.frame(minWidth: 170, alignment: .leading)
#else
return label
#endif
}
private func symbol(for kind: MediaLibrary.Kind) -> String {
switch kind {
case .movie: "film"