drago
drago

Reputation: 1283

How to pass variables to view presented in fullScreenCover in SwiftUI?

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:

enter image description here

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:

enter image description here

Upvotes: 1

Views: 1923

Answers (1)

comhendrik
comhendrik

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

Related Questions