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;
}
CodePudding user response:
You can create a Binding
inline using the init(get:set:)
initializer.
...
NavigationLink(
destination: ContentView(),
isActive: .init(
get: { activateNavigation },
set: { activateNavigation = $0 }
),
label: { EmptyView() }
)
...
CodePudding user response:
If you inject the binding into your second View
it should work fine.
NavigationLink(destination: ContentView($activateNavigation), isActive: $activateNavigation, label: { EmptyView() })
struct ContentView: View {
@Binding var activateNavigation: Bool
init(_ activateNavigation: Binding<Bool>) {
self.activateNavigation = activateNavigation
}
}
Bindings are persisted throughout view routes, so if you now set activateNavigation
in ContentView
it will update in LoadingScreen
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.