skip to Main Content

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!

3

Answers


  1. 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
                }
            }
        }
    }
    
    Login or Signup to reply.
  2. 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
                }
            }
        }
    }
    
    Login or Signup to reply.
  3. 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
                    }
                }
        }
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search