Duck
Duck

Reputation: 36003

NavigationLInk – Adding a delay before switching to a view

I have this navigation link like this:

NavigationLink(destination: MyForm(item))

I want an animation to perform on the main view, where the navigation link is, before switching to MyForm.

If I do not do that, the animation I want to perform mixes with the animation performed by the NavigationLink itself, as it switch to MyForm and the result is ugly as hell.

I want to add a delay before MyForm loads, after tapping on the navigation link.

Is that possible?

Upvotes: 1

Views: 1105

Answers (2)

RelativeJoe
RelativeJoe

Reputation: 5094

Using a custom container you can retain the same implementation as NavigationLink:

public struct DelayedNavigationLink<Destination: View, Content: View>: View {
    @State private var activate = false
    private let delay: TimeInterval
    private let content: Content
    private let destination: Destination
    public init(destination: Destination, @ViewBuilder content: () -> Content) {
        self.content = content()
        self.destination = destination
        self.delay = 0
    }
    private init(delay: TimeInterval, destination: Destination, content: Content) {
        self.content = content()
        self.destination = destination
        self.delay = delay
    }
    public var body: some View {
        Button(action: {
            DispatchQueue.main.asyncAfter(deadline: .now() + delay) {
                activate = true
            }
        }) {
            content
        }.background(
            NavigationLink(destination: destination, isActive: $activate) {
                Color.clear
            }
        )
    }
    public func delayed(by delay: TimeInterval) -> Self {
        DelayedNavigationLink(delay: delay, destination: destination, content: content)
    }
}

Example:

struct Test: View {
    var body: some View {
        DelayedNavigationLink(destination: Text("destination")) {
            Text("Navigate")
        }.delayed(by: 10)
    }
}

Upvotes: 4

Namra Parmar
Namra Parmar

Reputation: 255

You can do this using navigationLink like following : -

NavigationLink(destination: MyForm(item),isActive: $goNext,label:{}
            ).isDetailLink(false) 

Where go next is bool value. Now create a button and delay the action

    Button {
       //Let's say you have to delay navigation for 3 seconds 
       DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
            goNext = true     
       }
       //If you have different property for starting animation you can do that here as well
    } label: {
        Text("Go Next")
    }

Upvotes: -1

Related Questions