Last active
April 15, 2021 00:55
-
-
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.
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
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