I have a SwiftData model Player and there should only ever be 0 or 1 in the database. When the user is on the Main Menu and taps to Start a New Game, I walk them through a couple of screens to pick the options for the game. Once all of the options are chosen, I delete all existing Player objects and insert a new one. Then I dismiss all of those options picking screens.
Then what I want to happen is to automatically show the game view. But I'm not sure how to bind my .fullScreenCover() to the Player.isShown property on the first element in my SwiftData @Query.
The code below doesn't work because: Cannot convert value of type 'Bool?' to expected argument type 'Binding<Bool>'
I'm still very new to Swift and SwiftUI, so my grasp on bindables and observables is still tenuous.
struct RootContentView: View {
@Query var activeplayers: [Player] // should only ever be 0 or 1
var body: some View {
ZStack {
// stuff
}
.fullScreenCover(isPresented: activeplayers.first?.isshown content: {
GameView()
})
}
}
How can I automatically show my GameView screen based on the optional first element in my SwiftData @Query?
I also tried just querying to see if any players exist with .isShown == true and then binding to $activeplayers.isEmpty (this is the reverse of the logic I actually want, but I was just trying to find SOME way to distill the data down to a single bool property and I figured I could work on reversing the logic later) but that didn't work either:
@Query (filter: #Predicate<Player> {
$0.isshown == true
}) var activeplayers: [Player]
// ...
// without the $, gives the error:
// Cannot convert value of type 'Bool' to expected argument type 'Binding<Bool>'
.fullScreenCover(isPresented: activeplayers.isEmpty content: {
GameView()
})
// with the $, gives the error:
// Cannot find '$activeplayers' in scope
.fullScreenCover(isPresented: $activeplayers.isEmpty content: {
GameView()
})
You could try this simple approach, using an extra @State var shouldShow
and setting it in .onAppear {...} as shown in the example code
struct RootContentView: View {
@Environment(\.modelContext) private var modelContext
@Query var activeplayers: [Player]
@State var shouldShow = false // <-- here
var body: some View {
VStack {
Text("testing")
}
.fullScreenCover(isPresented: $shouldShow) { // <-- here
GameView()
}
// -- here
.onAppear {
if let player = activeplayers.first, let doShow = player.isshown {
shouldShow = doShow
}
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With