Die Seitenleiste war zu hoch — und der Player ging deshalb hinaus
Dreimal habe ich an den Rändern geschraubt, und dreimal war es nicht das.
Der Fehler sass in der Navigation und zeigte sich im Player.
**Gemessen statt vermutet.** Auf einem iPhone Pro Max im Querformat:
Fenster 956×440, Rand 0,62,62,20 → erwartet 832×420
Wurzel 832×558,67 @62,−69,33 → 138,67 zu hoch
Der Wurzelbaum ist zu gross für den Vorschlag und wird darin zentriert;
(420 − 558,67) / 2 ergibt exakt −69,33. Der Player liegt als Überlagerung
darin und erbt den Kasten — oben fielen neunundsechzig Punkte heraus,
unten neunundvierzig. Genau dort sitzen Kopfzeile und Zeitangaben.
**Die Ursache:** `FlixySidebar` war eine `VStack` ohne Bildlaufansicht,
mit dem Kommentar „die Einträge sind wenige und passen". Auf einem iPad
und im Hochformat stimmt das. Ein grosses iPhone ist quer
vierhundertvierzig Punkte hoch, und die Leiste braucht mit Kopf, Gruppen,
Trenner und Kontozeile gut fünfhundertdreissig. Eine `VStack` schrumpft
dann nicht — sie überragt, der `HStack` nimmt das Maximum, und alles
darüber wächst mit.
Deshalb war es nur dort zu sehen: nur auf einem grossen iPhone ist die
Anordnung quer `regular`, und nur dann gibt es überhaupt eine
Seitenleiste. Auf einem 17 Pro ist quer `compact` — dort stimmte jede
Messung, und genau deshalb konnte ich es dreimal nicht nachstellen.
Jetzt scrollt die Leiste, wenn sie muss (`basedOnSize`). Wo die Einträge
passen, sieht man keinen Unterschied. Nachgemessen: Wurzel 832×420,
Rahmen des Players 956×440 @0,0 — deckungsgleich mit dem Fenster.
**Mitgenommen:** `statusBarHeight` kam aus `proxy.safeAreaInsets.top` und
ging über `topInset` in einen `safeAreaInset` am selben Baum zurück. Das
Layout lief dadurch in Runden auf die richtige Grösse zu, jede Runde
zweiundsechzig Punkte. Der Wert kommt jetzt aus dem Fenster, das ihn ohne
Rückkopplung kennt — eine Runde statt drei.
`ScreenSafeArea` liegt dafür nicht mehr beim Player, sondern bei den
Modellen: es beantwortet jetzt für zwei Stellen dieselbe Frage.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
7bcef03c25
commit
5f635c699a
@@ -113,12 +113,31 @@ struct RootView: View {
|
||||
}
|
||||
.background(Color.flixyCanvas)
|
||||
.environment(topChrome)
|
||||
// Hier und nicht weiter innen: ab dem `HStack` wird der obere
|
||||
// Sicherheitsrand ignoriert, damit der Inhalt bis an den
|
||||
// Bildschirmrand reicht. Wer danach misst, bekommt null.
|
||||
.onGeometryChange(for: CGFloat.self) { proxy in
|
||||
proxy.safeAreaInsets.top
|
||||
} action: { statusBarHeight = $0 }
|
||||
// **Aus dem Fenster, nicht aus dem Layout — und das ist der ganze
|
||||
// Punkt.**
|
||||
//
|
||||
// Hier stand `proxy.safeAreaInsets.top`, und daraus wurde eine
|
||||
// Rückkopplung: der gemessene Rand geht in `topInset`, `topInset`
|
||||
// geht in einen `safeAreaInset` am Inhalt, und der verändert genau
|
||||
// den Rand, der gerade gemessen wurde. Das Layout lief danach in
|
||||
// Runden auf die richtige Grösse zu — jede Runde zweiundsechzig
|
||||
// Punkte, also genau eine Statusleiste — und blieb auf halbem Weg
|
||||
// stehen, weil SwiftUI irgendwann aufhört, neu zu rechnen.
|
||||
//
|
||||
// Sichtbar war das nur im Querformat auf einem grossen iPhone: dort
|
||||
// ist die Anordnung `regular`, nur dort gibt es den `safeAreaInset`,
|
||||
// und nur dort ist der Rand vorher und nachher verschieden. Der
|
||||
// Wurzelbaum war dadurch hundertachtzehn Punkte höher als der
|
||||
// Bildschirm und begann neunundsechzig darüber — und der Player, der
|
||||
// als Überlagerung darin liegt, ging oben und unten hinaus. Genau so
|
||||
// verschwanden Kopfzeile und Zeitangaben.
|
||||
//
|
||||
// Das Fenster kennt seinen Rand ohne Rückkopplung. Die Grösse bleibt
|
||||
// der Anlass zum Nachfragen, der **Wert** kommt von aussen.
|
||||
.onGeometryChange(for: CGSize.self) { proxy in
|
||||
proxy.size
|
||||
} action: { _ in statusBarHeight = ScreenSafeArea.current.top }
|
||||
.onAppear { statusBarHeight = ScreenSafeArea.current.top }
|
||||
// Hier statt in der Scene: eine View wertet Beobachtungsänderungen
|
||||
// zuverlässig neu aus, ein Scene-Body nicht.
|
||||
.flixyAccent(theme)
|
||||
|
||||
Reference in New Issue
Block a user