-
-
Save azamsharpschool/9e7732f85f85353de069425454d0e8dc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ContentView.swift | |
// Learn | |
// | |
// Created by Mohammad Azam on 8/14/24. | |
// | |
import SwiftUI | |
enum Sheet: Identifiable, Hashable { | |
case settings | |
case contact(String) | |
var id: Self { self } | |
} | |
struct SheetAction { | |
typealias Action = (Sheet, (() -> Void)?) -> Void | |
let action: Action | |
func callAsFunction(_ sheet: Sheet, _ dismiss: (() -> Void)? = nil) { | |
action(sheet, dismiss) | |
} | |
} | |
struct ShowSheetKey: EnvironmentKey { | |
static var defaultValue: SheetAction = SheetAction { _, _ in } | |
} | |
extension EnvironmentValues { | |
var showSheet: (SheetAction) { | |
get { self[ShowSheetKey.self] } | |
set { self[ShowSheetKey.self] = newValue } | |
} | |
} | |
struct SheetView: View { | |
let sheet: Sheet | |
var body: some View { | |
switch sheet { | |
case .settings: | |
Text("Settings") | |
case .contact(let name): | |
Text("Contacting \(name)") | |
} | |
} | |
} | |
// THIS IS JUST FOR THE PREVIEWS | |
struct ContentViewContainer: View { | |
@State private var selectedSheet: Sheet? | |
@State private var onSheetDismiss: (() -> Void)? | |
var body: some View { | |
ContentView() | |
.environment(\.showSheet, SheetAction(action: { sheet, dismiss in | |
selectedSheet = sheet | |
onSheetDismiss = dismiss | |
})) | |
.sheet(item: $selectedSheet, onDismiss: onSheetDismiss) { sheet in | |
SheetView(sheet: sheet) | |
} | |
} | |
} | |
struct ContentView: View { | |
@Environment(\.showSheet) private var showSheet | |
private func settingsScreenDismissed() { | |
print("settingsScreenDismissed") | |
} | |
var body: some View { | |
VStack { | |
Button("Show Settings Screen") { | |
showSheet(.settings, settingsScreenDismissed) | |
} | |
Button("Show Contact Screen") { | |
showSheet(.contact("John Doe")) | |
} | |
} | |
.padding() | |
} | |
} | |
#Preview { | |
ContentViewContainer() | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// LearnApp.swift | |
// Learn | |
// | |
// Created by Mohammad Azam on 8/14/24. | |
// | |
import SwiftUI | |
@main | |
struct LearnApp: App { | |
@State private var selectedSheet: Sheet? | |
@State private var onSheetDismiss: (() -> Void)? | |
var body: some Scene { | |
WindowGroup { | |
NavigationStack { | |
ContentView() | |
.environment(\.showSheet, SheetAction(action: { sheet, dismiss in | |
selectedSheet = sheet | |
onSheetDismiss = dismiss | |
})) | |
.sheet(item: $selectedSheet, onDismiss: onSheetDismiss) { sheet in | |
SheetView(sheet: sheet) | |
} | |
} | |
} | |
} | |
} |
abinhho
commented
Sep 6, 2024
- How to know there is any sheet opening?
- How to close sheet from sheet content (sheet close button)
import SwiftUI
enum Sheet: Identifiable {
case settings
case contact(String)
var id: String {
switch self {
case .settings:
return "settings"
case .contact(let name):
return "contact_\(name)"
}
}
}
struct SheetManager: ViewModifier {
@Binding var activeSheet: Sheet?
func body(content: Content) -> some View {
content
.sheet(item: $activeSheet) { sheet in
SheetView(sheet: sheet, dismiss: { activeSheet = nil })
}
}
}
extension View {
func managedSheet(activeSheet: Binding<Sheet?>) -> some View {
self.modifier(SheetManager(activeSheet: activeSheet))
}
}
struct SheetView: View {
let sheet: Sheet
let dismiss: () -> Void
var body: some View {
VStack {
sheetContent
Button("Close", action: dismiss)
}
}
@ViewBuilder
private var sheetContent: some View {
switch sheet {
case .settings:
Text("Settings")
case .contact(let name):
Text("Contacting \(name)")
}
}
}
struct ContentView: View {
@State private var activeSheet: Sheet?
var body: some View {
VStack {
Button("Show Settings") {
activeSheet = .settings
}
Button("Show Contact") {
activeSheet = .contact("John Doe")
}
}
.managedSheet(activeSheet: $activeSheet)
}
}
#Preview {
ContentView()
}
Swift 6 compiler generates "Static property 'defaultValue' is not concurrency-safe because it is nonisolated global shared mutable state" at
static var defaultValue: SheetAction = SheetAction { _, _ in }
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment