diff --git a/Flixy/Views/Navigation/FlixyNavigationBar.swift b/Flixy/Views/Navigation/FlixyNavigationBar.swift index f8206ab..2ce932d 100644 --- a/Flixy/Views/Navigation/FlixyNavigationBar.swift +++ b/Flixy/Views/Navigation/FlixyNavigationBar.swift @@ -178,7 +178,7 @@ struct FlixySidebar: View { if !isEditing { Button { - withAnimation(.snappy(duration: 0.25)) { placement = .top } + placement = .top } label: { Image(systemName: "rectangle.topthird.inset.filled") .font(.flixyRowHeader) @@ -337,7 +337,7 @@ struct FlixyTopBar: View { var body: some View { HStack(spacing: FlixySpacing.tight) { Button { - withAnimation(.snappy(duration: 0.25)) { placement = .sidebar } + placement = .sidebar } label: { Image(systemName: "sidebar.leading") .font(.flixyBody) diff --git a/Flixy/Views/Navigation/RootView.swift b/Flixy/Views/Navigation/RootView.swift index d2f0400..72c1386 100644 --- a/Flixy/Views/Navigation/RootView.swift +++ b/Flixy/Views/Navigation/RootView.swift @@ -36,12 +36,25 @@ struct RootView: View { @AppStorage("flixy.navigation.customization") private var customization = TabViewCustomization() - /// Ob die Navigation an der Seite oder oben sitzt. + /// Ob die Navigation an der Seite oder oben sitzt — gespeichert. /// - /// Gespeichert, weil die Wahl dem Nutzer gehört und den Neustart - /// überleben muss. + /// Die Wahl gehört dem Nutzer und muss den Neustart überleben. @AppStorage("flixy.navigation.placement") - private var placement: NavigationPlacement = .sidebar + private var storedPlacement: NavigationPlacement = .sidebar + + /// Dieselbe Wahl, aber als Zustand dieser Ansicht. + /// + /// Der Umweg ist nötig, damit das Umschalten überhaupt zu sehen ist: + /// `@AppStorage` schreibt in die Voreinstellungen und meldet die Änderung + /// erst danach zurück. Sie kommt also außerhalb der Animation an, und die + /// Leiste sprang von einer Stellung in die andere, statt zu wandern. + /// + /// Hier ändert sich der Zustand sofort und im selben Zug; gespeichert wird + /// hinterher. + @State private var placement: NavigationPlacement = .sidebar + + /// Wie die Leiste umzieht. Kurz, aber sichtbar. + private static let placementAnimation: Animation = .snappy(duration: 0.32) /// Was der Nutzer an der Navigation umgestellt hat: Reihenfolge und was /// überhaupt dastehen soll. @@ -311,6 +324,8 @@ struct RootView: View { #endif } .miniPlayer(player, isVisible: playback.presentation == .mini) + .onAppear { placement = storedPlacement } + .onChange(of: placement) { _, new in storedPlacement = new } } @ViewBuilder @@ -320,7 +335,7 @@ struct RootView: View { FlixySidebar( groups: navigationGroups, selection: $selection, - placement: $placement, + placement: $placement.animation(Self.placementAnimation), layout: navigationLayout ) // Sie kommt von der Seite herein und geht dorthin zurück. Ohne das @@ -337,7 +352,7 @@ struct RootView: View { FlixyTopBar( groups: navigationGroups.map(visible), selection: $selection, - placement: $placement + placement: $placement.animation(Self.placementAnimation) ) Spacer(minLength: 0) }