Ask link action confirmations in an alert on tvOS

A tvOS sheet fills most of the screen, far too much for a two-button
question. The shared sheet host now presents link action confirmations
as an alert there, answering cancel when it goes away without a choice.
This commit is contained in:
Arkadiusz Fal
2026-10-07 23:59:44 +02:00
parent 33152f4371
commit bc6ad55f38
2 changed files with 64 additions and 25 deletions

View File

@@ -130,11 +130,14 @@ private struct AppSheetHost: ViewModifier {
func body(content: Content) -> some View {
content
.environment(\.presentAppSheet, PresentAppSheetAction { sheet = $0 })
.sheet(item: $sheet) { sheet in
.sheet(item: presentedSheet) { sheet in
sheetContent(for: sheet)
.sheetToastOverlay(scope: sheetToastLevel.scope, depth: sheetToastLevel.depth)
.environment(\.sheetToastLevel, sheetToastLevel)
}
#if os(tvOS)
.linkActionConfirmationAlert(pendingConfirmation) { sheet = nil }
#endif
// Declared before the request observer so a deep link that both
// dismisses and presents ends with its own sheet up.
.onChange(of: dismissGeneration) { _, _ in
@@ -145,6 +148,26 @@ private struct AppSheetHost: ViewModifier {
}
}
/// The sheet to present as a sheet. On tvOS a link action confirmation
/// is a compact alert instead: a tvOS sheet fills most of the screen.
private var presentedSheet: Binding<AppSheet?> {
#if os(tvOS)
Binding {
if case .linkActionConfirmation = sheet { return nil }
return sheet
} set: { sheet = $0 }
#else
$sheet
#endif
}
#if os(tvOS)
private var pendingConfirmation: LinkActionConfirmation? {
if case .linkActionConfirmation(let confirmation) = sheet { return confirmation }
return nil
}
#endif
private var dismissGeneration: Int? {
dismissesOnExternalNavigation ? appEnvironment?.navigationCoordinator.dismissPresentationsGeneration : nil
}