Hinter der Insel läuft jetzt das Wasser durch
Der schwarze Streifen über der Navigation war kein gezeichneter Balken, sondern fehlender Inhalt: der gesamte Baum saß innerhalb des Sicherheitsrands. Deshalb erreichte kein noch so gut gesetzter Rand weiter unten die Fläche darüber — Inhalt kam dort nie hin. Jetzt reißt der HStack den Rand oben auf und gibt den Platz kontrolliert zurück: Seitenleiste und Insel bekommen ihren Abstand zur Statusleiste explizit, der Inhalt bekommt ihn als Sicherheitsrand. Der Aufmacher nimmt ihn sich wieder — um genau diese Strecke höher und um genau diese Strecke größer, sodass unten alles bleibt, wo es war. Dazu ein knapper Verlauf oben, damit Uhrzeit und Batterie auch über einem hellen Bild lesbar bleiben. Und die Leiste oben fährt beim Scrollen weg. Nur sie: der Sicherheitsrand darunter bleibt stehen, sonst ruckte die Seite bei jedem Ein- und Ausblenden unter dem Finger weg. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
9b3c6e2030
commit
81e22c4f97
@@ -64,6 +64,23 @@ struct HeroCarousel: View {
|
||||
@Environment(\.flixyAccent) private var accent
|
||||
@Environment(FlixySession.self) private var session
|
||||
@Environment(\.horizontalSizeClass) private var sizeClass
|
||||
@Environment(TopChrome.self) private var chrome
|
||||
|
||||
/// Wie weit der Aufmacher nach oben unter die Insel greift.
|
||||
///
|
||||
/// Der Inhalt beginnt unter der Insel — das ist für Reihen und Listen
|
||||
/// richtig, für den Aufmacher aber nicht: er ist das Bild, auf dem die
|
||||
/// Insel schweben soll, und ein Bild, das an ihrer Unterkante anfängt,
|
||||
/// lässt darüber einen schwarzen Streifen stehen, den nie etwas füllt.
|
||||
///
|
||||
/// Also nimmt er sich den Platz zurück: um genau diese Strecke höher und
|
||||
/// um genau diese Strecke größer. Unten ändert sich dadurch nichts, die
|
||||
/// Reihen bleiben, wo sie waren.
|
||||
///
|
||||
/// Auf dem iPhone null — dort schwebt nichts über dem Inhalt.
|
||||
private var overlap: CGFloat {
|
||||
sizeClass == .compact ? 0 : chrome.inset
|
||||
}
|
||||
|
||||
private var currentIndex: Int {
|
||||
items.firstIndex { $0.id == shownID } ?? 0
|
||||
@@ -95,7 +112,7 @@ struct HeroCarousel: View {
|
||||
//
|
||||
// Auf einem schmalen Gerät nicht: dort ist der Aufmacher hochkant
|
||||
// und rechnet sich seine Höhe aus der Breite aus.
|
||||
.modifier(HeroHeight(fraction: sizeClass == .compact ? nil : 0.82))
|
||||
.modifier(HeroHeight(fraction: sizeClass == .compact ? nil : 0.82, extra: overlap))
|
||||
// **Kein** Seitenverhältnis hier: der Aufmacher bringt sein
|
||||
// eigenes mit, und eines darüber legte ihn auf die Breite des
|
||||
// Inhaltsbereichs fest. Weil er nach links unter die Seitenleiste
|
||||
@@ -136,6 +153,10 @@ struct HeroCarousel: View {
|
||||
|
||||
if items.count > 1 { indicator }
|
||||
}
|
||||
// Zieht den ganzen Aufmacher unter die Insel. Zusammen mit der
|
||||
// zusätzlichen Höhe oben hebt sich das unten auf: er beginnt am
|
||||
// Bildschirmrand und endet, wo er vorher endete.
|
||||
.padding(.top, -overlap)
|
||||
.task(id: shownID) { await advance() }
|
||||
.onChange(of: items.map(\.id), initial: true) { _, ids in
|
||||
// Beim ersten Zeichnen und nach jedem Aktualisieren: steht die
|
||||
@@ -217,10 +238,13 @@ struct HeroCarousel: View {
|
||||
/// Drehen neu geladen statt mitzuwandern.
|
||||
private struct HeroHeight: ViewModifier {
|
||||
let fraction: CGFloat?
|
||||
/// Was über den Anteil hinaus dazukommt: der Platz unter der Insel, den
|
||||
/// der Aufmacher mitfüllt, weil er nach oben unter sie greift.
|
||||
let extra: CGFloat
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
if let fraction {
|
||||
content.containerRelativeFrame(.vertical) { height, _ in height * fraction }
|
||||
content.containerRelativeFrame(.vertical) { height, _ in height * fraction + extra }
|
||||
} else {
|
||||
content
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ struct HomeView: View {
|
||||
.padding(.bottom, FlixySpacing.section)
|
||||
}
|
||||
.scrollIndicators(.never)
|
||||
.flixyRevealsTopChrome()
|
||||
}
|
||||
|
||||
/// Bringt die Reihen vom Server in die Form, die eingestellt ist.
|
||||
|
||||
Reference in New Issue
Block a user