Re-create the SwiftUI navigation push / pop transition without using a NavigationStack, while keeping a static background

👋

I recently had to implement a paged navigation flow (akin to NavigationStack) where a user would fill a form on multiple pages, while the background stays the same (a paused video).

Basically, the background stays the same while the content changes above.

However, to the best of my knowledge, this is not something that is possible with either NavigationView nor NavigationStack, the background will always be animated and move with the pushed / popped view.

However, we really want to keep the "push" and "pop" animations, so we came up with a rather rudimentary solution that fakes a navigation stack and plays with transitions in order to give the impression of a real push / pop

struct MainView: View {

  // Handles routes, history, push and pop
  private var coordinator: Coordinator

  @State private var transition: AnyTransition = .opacity

  var body: some View {
    VStack {
      coordinator.route.view
        .transition(transition)
    }
  }

  func push() {
    transition = .asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading))
    coordinator.push(...)
  }

  func pop() {
    transition = .asymmetric(insertion: .move(edge: .leading), removal: .move(edge: .trailing))
    coordinator.pop()
  }
}

Whenever we push / pop, the coordinator.route property is changed and transitions to the new view. But I'm having trouble with the transition, it does not work on the first move but is fine after that.

My guess is that when pushing or popping, the new transition is applied only on the new pushed / popped view rather than on the already shown view.

How can I change the transition and then only push / pop the new content ?

Answered by DTS Engineer in 798474022

Have you considered creating a custom Transition instead? It lets you define specific effects for different TransitionPhase, whether a view is appearing or disappearing.

Create custom visual effects with SwiftUI WWDC does into more details on custom transitions.

However, to the best of my knowledge, this is not something that is possible with either NavigationView nor NavigationStack, the background will always be animated and move with the pushed / popped view.

If you're interested in specifying a navigation transition style, using the navigationTransition(_:) modifier then I would suggest you review Enhance your UI animations and transitions WWDC session. It covers the topic as well and includes some code snippets examples.

Have you considered creating a custom Transition instead? It lets you define specific effects for different TransitionPhase, whether a view is appearing or disappearing.

Create custom visual effects with SwiftUI WWDC does into more details on custom transitions.

However, to the best of my knowledge, this is not something that is possible with either NavigationView nor NavigationStack, the background will always be animated and move with the pushed / popped view.

If you're interested in specifying a navigation transition style, using the navigationTransition(_:) modifier then I would suggest you review Enhance your UI animations and transitions WWDC session. It covers the topic as well and includes some code snippets examples.

Re-create the SwiftUI navigation push / pop transition without using a NavigationStack, while keeping a static background
 
 
Q