Created
January 24, 2022 07:02
-
-
Save ihamadfuad/09c018851af94fef1b70ba347bde22b4 to your computer and use it in GitHub Desktop.
SwiftUI: Present Sheet From Anywhere Using @Environment
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
// ºººº----------------------------------------------------------------------ºººº \\ | |
// | |
// Credit Hamad Fuad. | |
// | |
// Author: Hamad Fuad | |
// Email: [email protected] | |
// | |
// Created At: 24/01/2022 | |
// Last modified: 24/01/2022 | |
// | |
// ºººº----------------------------------------------------------------------ºººº \\ | |
import SwiftUI | |
// Step 1: | |
/** | |
1. Create state object in main view: | |
@StateObject var sheetViewPresenter = SheetViewPresenter() | |
2. Attach .environment(_ key:...) to main view: | |
.environment(\.sheetViewPresenterKey, sheetViewPresenter) | |
3. Attach sheet(...) to main view: | |
.sheet(item: $sheetViewPresenter.activeSheet) { activeSheet in | |
// in general, you don't have to check for each case. However, you can add special case and handle separately here. | |
switch activeSheet { | |
default: | |
sheetViewPresenter.currentSheetView | |
} | |
} | |
*/ | |
// Step 2: | |
/** | |
Usage: | |
1. Declare in any child view: | |
@Environment(\.sheetViewPresenterKey) var sheetViewPresenter | |
2. Present sheet view: | |
sheetViewPresenter.currentSheetView = AnyView(Text("Hello")) | |
DispatchQueue.main.async { | |
sheetViewPresenter.activeSheet = .any | |
} | |
*/ | |
struct SheetViewPresenterKey: EnvironmentKey { | |
static let defaultValue = SheetViewPresenter() | |
} | |
extension EnvironmentValues { | |
var sheetViewPresenterKey: SheetViewPresenter { | |
get { return self[SheetViewPresenterKey.self] } | |
set { self[SheetViewPresenterKey.self] = newValue } | |
} | |
} | |
class SheetViewPresenter: ObservableObject { | |
enum sheetType: String, Identifiable { | |
case any | |
var id: String { | |
rawValue | |
} | |
} | |
@Published var isSheetViewPresented = false | |
@Published var currentSheetView: AnyView? = nil | |
@Published var activeSheet: sheetType? = nil { | |
willSet { | |
isSheetViewPresented = newValue != nil | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'd love to hear your feedback on this approach.