UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

Initialization Issue

Forums > SwiftUI

@ASH  

I have some lengthy code with explicit colors, that works . I have reduced the cogent parts to the simplification below . My View Model is passed to my view as an environment object.

struct ConteView: View {

@EnvironmentObject var game: colorGameVM ... // a bunch of @State vars ...

@State var angGrad: [Color] = [Color.red,Color.white,Color.blue]

var body: some View { // bunch of stuff }

}

I want to dynamically use colors from my View Model, so I changed it like this

struct ConteView: View {

@EnvironmentObject var game: colorGameVM ... // a bunch of @State vars ...

@State var angGrad: [Color] = [game.color1,game.color2,game.color3]

var body: some View { // bunch of stuff }

}

and got the "Cannot use instance member 'game' within property initializer; property initializers run before 'self' is available" error on the angGrad line.

I left the @State type def and moved angGrad code into an initializer but get an error "Variable 'self.manager' used before being initialized" in the init. I don't understand what this means. I cannot bring the game var into the init because as an Environment Object it's a get only property.

struct ConteView: View {

@EnvironmentObject var game: colorGameVM ... // a bunch of @State vars ...

@State var angGrad: [Color]

init() { self.angGrad = [game.color1,game.color2,game.color3] }

var body: some View { // bunch of stuff }

}

Any suggestions on how to achieve this? BTW, I know I can access the game.color directly in my View, the angGrad is a an array used for a background color gradient.

2      

The explanation why you can't use an EnvironmentObject in init is explained by roosterboy here.

Because when init is called on a View, that's no guarantee it will actually be displayed on screen. (e.g., the destination of a NavigationLink gets its init called when the NavigationLink is rendered, even if the user never follows the link) It's not until the body is rendered that it will be displayed and so that's when an environment needs to exist. If you used an environment object or value at init time, it could be different by the time the View is actually rendered.

Please, use code tags next time you describe your problem because it's easier to understand what's your code.

One solution could be that your ViewModel is passed in the init and it's not a StateObject but a ObserverdObject.

2      

@ASH  

Thank you @Hatsushira for that explanation. I will probably just rework the code to access the game.color values directly.

2      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

Sponsor Hacking with Swift and reach the world's largest Swift community!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.