Reputation: 53
In my app I navigate to a page (say, page 2), then wish to show an animation (and nothing else) on the page, before executing and moving to a new view using NavigationView. In other words, I'd like the NavigationView destination view to load after a delay timer (say 3 seconds), without the user having to click a button. During that 3 seconds, the animation will be running. The animation and the NavigationView work fine on their own, but my current solution requires the user to click a button/text to move to the destination view, which is a little clunky. I can't find a solution anywhere. Any help would be greatly appreciated. Thanks!
Upvotes: 0
Views: 2849
Reputation: 777
You can use DelayedNavigationLink
, see implementation below. Usage example:
var body: some View {
VStack {
Text("Navigation link will run in 3 seconds")
DelayedNavigationLink(delay: .seconds(3)) {
Text("Destination view")
}
}
}
Implementation:
struct DelayedNavigationLink<Destination: View, Label: View>: View {
@State private var linkIsActive = false
private let delay: DispatchTimeInterval
private var destination: () -> Destination
private var label: () -> Label
init(delay: DispatchTimeInterval, destination: @escaping () -> Destination) where Label == EmptyView {
self.init(delay: delay, destination: destination, label: EmptyView.init)
}
init(delay: DispatchTimeInterval, destination: @escaping () -> Destination, label: @escaping () -> Label) {
self.delay = delay
self.destination = destination
self.label = label
}
var body: some View {
NavigationLink(isActive: $linkIsActive, destination: destination, label: label)
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
linkIsActive = true
}
}
}
}
Upvotes: 0
Reputation: 9705
Alternatively:
struct MyView: View {
@State var pushNewView: Bool = false
var body: some View {
NavigationView {
NavigationLink(isActive: $pushNewView) {
Text("Second View")
} label: {
Text("First View") //Replace with some animation content
}
}
.onAppear {
DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
pushNewView = true
}
}
}
}
Upvotes: 2
Reputation: 1209
This should work:
struct MyView: View {
@State var pushNewView: Bool = false
var body: some View {
NavigationView {
NavigationLink(isActive: $pushNewView) {
Text("Second View")
} label: {
Text("First View") //Replace with some animation content
}
}
.onAppear {
Timer.scheduledTimer(withTimeInterval: 3, repeats: false) { _ in
pushNewView = true
}
}
}
}
Upvotes: 4