Files
yattee/Yattee/Views/Components/TVSidebarDetailContainer.swift
Arkadiusz Fal 5b9cd8c521 Dismiss tvOS sidebar detail pages when sidebar selection changes
tvOS's sidebarAdaptable TabView leaves the previously-pushed detail view
visible after the user picks another sidebar item, until they manually
press Menu. Broadcast a notification on tab change so any pushed
TVSidebarDetailContainer dismisses itself, and reset each tab's
NavigationPath. Also drop a redundant inner NavigationStack in the tvOS
SettingsView so subpages register on the tab's outer stack.
2026-05-08 19:35:36 +02:00

78 lines
2.4 KiB
Swift

//
// TVSidebarDetailContainer.swift
// Yattee
//
// Decorates a tvOS detail screen with a fixed 400pt left sidebar showing
// a large SF Symbol and a title, matching the look of tvOS settings.
//
#if os(tvOS)
import SwiftUI
extension Notification.Name {
static let yatteeTVForcePopDetail = Notification.Name("yatteeTVForcePopDetail")
}
struct TVSidebarDetailContainer<Content: View>: View {
let content: Content
var systemImage: String?
var title: String?
var showsDismissButton: Bool
@Environment(\.dismiss) private var dismiss
init(
systemImage: String? = nil,
title: String? = nil,
showsDismissButton: Bool = false,
@ViewBuilder content: () -> Content
) {
self.content = content()
self.systemImage = systemImage
self.title = title
self.showsDismissButton = showsDismissButton
}
var body: some View {
content
.focusSection()
.safeAreaInset(edge: .leading) {
if let systemImage {
VStack(spacing: 16) {
Image(systemName: systemImage)
.font(.system(size: 80))
.foregroundStyle(.secondary)
if let title {
Text(title)
.font(.title3)
.fontWeight(.semibold)
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
}
}
.allowsHitTesting(false)
.frame(width: 400)
} else {
Spacer()
.frame(width: 400)
.allowsHitTesting(false)
}
}
.toolbar {
if showsDismissButton {
ToolbarItem(placement: .cancellationAction) {
Button {
dismiss()
} label: {
Label(String(localized: "common.done"), systemImage: "chevron.backward")
}
}
}
}
.onReceive(NotificationCenter.default.publisher(for: .yatteeTVForcePopDetail)) { _ in
dismiss()
}
}
}
#endif