I have a loading screen that should navigate to the contentview once a few images have finished loading. I load the images using the first two functions and finally trigger navigation to content view. Navigation is triggered when a state variable activateNavigation turns true. The issue is I need to change state in a function outside the struct. I can’t seem to figure out how to do this, you can see it in the final code snippet below.
LoadingScreen().onAppear(){
getImages();
convertImages();
triggerNavigationToContentView();
}
struct LoadingScreen: View{
@State var text = ""
@State var activateNavigation = false
let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
var body: some View{
NavigationView{
VStack{
Text("Loading images (text)")
.font(.system(size: 24)).bold()
.transition(.slide)
.onReceive(timer, perform: {(_) in
if self.text.count == 3 {
self.text = ""
} else {
self.text += "."
}
})
.onAppear(){
self.text = "."
}
NavigationLink(destination: ContentView(), isActive: $activateNavigation, label: { EmptyView() })
}
}
}
}
triggerNavigationToContentView(){
activateNavigation = true;
}
2
Answers
You can create a
Binding
inline using theinit(get:set:)
initializer.If you inject the binding into your second
View
it should work fine.Bindings are persisted throughout view routes, so if you now set
activateNavigation
inContentView
it will update inLoadingScreen
too (and vice versa).You can use Bindings in initialisers for other structs too if you need to trigger the flow elsewhere. I don’t recommend global functions.
Note that using
$activateNavigation
implicitly converts the@State
into an@Binding
, no boilerplate needed.