Reputation: 1283
I've been struggling for a while now to pass a few variables from one view to another view that's presented in fullScreenCover mode in my SwiftUI project.
Here's the scenario:
I have firstView with a variable like so:
struct homeView: View {
@State var audioPlayerBG = ""
@State var show = true
init(tabSelection: Binding<Int>) {
_tabSelection = tabSelection
}
var body: some View {
NavigationView {
ZStack {
}
}
.fullScreenCover(isPresented: $show, content: secondView(audioPlayerBG: audioPlayerBG))
}
and My secondView is simply this:
import SwiftUI
struct secondView: View {
let audioPlayerBG: String
var body: some View {
Text("second View")
}
}
struct secondView_Previews: PreviewProvider {
static var previews: some View {
audioPlayer(audioPlayerBG: "")
}
}
However, when I try to compile my app, I get this error in my firstView:
If I change the fullScreenCover
code to this, it works but this way I won't be able to pass any variables to my secondView!
.fullScreenCover(isPresented: $show, content: secondView.init)
could someone please advice on this?
Edit:
I've tried the following and I get a Fatal error when I run my code:
ContentView:
class GameSettings: ObservableObject {
@Published var score = 0
}
struct ContentView: View {
let defaults = UserDefaults.standard
@StateObject var settings = GameSettings()
var body: some View {
TabView() {
firstView()
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image(systemName: "person.crop.circle")
Text("Profile")
}.tag(0)
secondView()
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image(systemName: "person.crop.circle")
Text("Profile")
}.tag(0)
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
firstView:
import SwiftUI
struct firstView: View {
@State private var showAudioPlayer = false
@StateObject var settings = GameSettings()
var body: some View {
NavigationView {
Button("Show details") {
showAudioPlayer.toggle()
settings.score += 1
}
}
.environmentObject(settings)
.fullScreenCover(isPresented: $showAudioPlayer, content: secondView.init)
}
}
And the secondView:
import SwiftUI
struct secondView: View {
@EnvironmentObject var settings: GameSettings
var body: some View {
Text("Score: \(settings.score)")
}
}
struct vecondView_Previews: PreviewProvider {
static var previews: some View {
secondView()
}
}
When I run my code above, I get this error:
Upvotes: 1
Views: 1923
Reputation: 289
This is the code you can use.
import SwiftUI
class GameSettings: ObservableObject {
@Published var score = 0
}
struct ContentView: View {
let defaults = UserDefaults.standard
@StateObject var settings = GameSettings()
var body: some View {
TabView() {
firstView()
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image(systemName: "person.crop.circle")
Text("Profile")
}.tag(0)
secondView(settings: settings)
.font(.system(size: 30, weight: .bold, design: .rounded))
.tabItem {
Image(systemName: "person.crop.circle")
Text("Profile")
}.tag(0)
}
}
}
struct firstView: View {
@State private var showAudioPlayer = false
@StateObject var settings = GameSettings()
var body: some View {
NavigationView {
Button("Show details") {
showAudioPlayer.toggle()
settings.score += 1
}
.fullScreenCover(isPresented: $showAudioPlayer, content: {
secondView(settings: settings)
})
}
}
}
struct secondView: View {
var settings: GameSettings
var body: some View {
Text("Score: \(settings.score)")
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
But this would make more sense because You can close the full screen cover and you have no TabView().
import SwiftUI
class GameSettings: ObservableObject {
@Published var score = 0
}
struct ContentView: View {
@StateObject var settings = GameSettings()
var body: some View {
firstView(settings: settings)
.font(.system(size: 30, weight: .bold, design: .rounded))
}
}
struct firstView: View {
@State private var showAudioPlayer = false
var settings: GameSettings
var body: some View {
NavigationView {
Button("Show details") {
showAudioPlayer.toggle()
settings.score += 1
}
.fullScreenCover(isPresented: $showAudioPlayer, content: {
secondView(settings: settings, showAudioPlayer: $showAudioPlayer)
})
}
}
}
struct secondView: View {
var settings: GameSettings
@Binding var showAudioPlayer: Bool
var body: some View {
VStack {
Text("Score: \(settings.score)")
Button(action: {
showAudioPlayer.toggle()
}, label: {
Text("Close")
})
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
Upvotes: 1