Skip to content

Instantly share code, notes, and snippets.

@alenm
Last active April 15, 2021 00:55
Show Gist options
  • Save alenm/ade5c5d2db4131ad029f963fc2c41719 to your computer and use it in GitHub Desktop.
Save alenm/ade5c5d2db4131ad029f963fc2c41719 to your computer and use it in GitHub Desktop.
Having multiple sheets within one SwiftUI view can happen. The `sheet(item:content:)` takes an item: Binding<Identifiable> which means in the latest swift you can use an Enum and switch on it in the content closure.
import SwiftUI
import Combine
// 01 Enum
enum Activesheet: Identifiable {
case twitter
case picker
case web
var id: String {
switch self {
case .twitter:
return "twitter"
case .picker:
return "picker"
case .web:
return "web"
}
}
}
// 02: Create an Observable Object called `Modal Manager`
class ModalManager: ObservableObject {
@Published var sheet: Activesheet?
}
struct ContentView: View {
// 03: @StateObject is a our ModalManager we defined earlier
@StateObject private var modalManager: ModalManager = ModalManager()
var body: some View {
VStack {
buttons
// 04 Pass in the Binding using $modalManager.sheet
}.sheet(item: $modalManager.sheet, onDismiss: didDismiss) { activeSheet in
switch activeSheet {
case .twitter:
Twitter(sheet: $modalManager.sheet) // This is a new view
case .picker:
Picker(sheet: $modalManager.sheet) // This is a new view
case .web:
Web(sheet: $modalManager.sheet) // This is a new view
}
}
}
private func didDismiss() {
print("Did dismiss")
self.modalManager.sheet = nil
}
// 05 We have our buttons. Nothing new except the action references the stateObject
private var buttons: some View {
Group {
Button(action: {
modalManager.sheet = .twitter
}, label: {
Text("Show Twitter")
})
Divider()
Button(action: {
modalManager.sheet = .picker
}, label: {
Text("Show Picker")
})
Divider()
Button(action: {
modalManager.sheet = .web
}, label: {
Text("Show Web ")
})
}
}
}
// 04 We have seperate views, that could contain it's own logic
// each view contains it's own @Binding.
struct Twitter: View {
@Binding var sheet: Activesheet?
var body: some View {
Button(action: {
self.sheet = nil
}, label: {
Text("Dismiss Twitter")
})
}
}
struct Picker: View {
@Binding var sheet: Activesheet?
var body: some View {
Button(action: {
self.sheet = nil
}, label: {
Text("Dismiss Picker")
})
}
}
struct Web: View {
@Binding var sheet: Activesheet?
var body: some View {
Button(action: {
self.sheet = nil
}, label: {
Text("Dismiss Web Picker")
})
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment