4

In UIKit-based application we can have custom navigation transitions using UIViewControllerAnimatedTransitioning protocol.

Is there an equivalent in SwiftUI?

I know we can already animate between removing and adding views. But how do we do this when we push and pop to the navigation stack?

3
  • Standard NavigationView does not allow customisation for transitions for now. You can use/create custom navigation instead. Consider for example this solution stackoverflow.com/a/59087574/12299030 Commented Aug 20, 2020 at 4:33
  • @Asperi That’s a terrible suggestion. This basically breaks any accessibility support built into UINavigationController, as well all the built-in tools provided. Just like it’s terrible when web “apps” do this, it’s equally terrible with SwiftUI. Commented Aug 21, 2020 at 22:14
  • The correct solution is to either wrap UINavigationController manually, or otherwise obtain a reference to it, which is rather simple. Commented Aug 21, 2020 at 22:15

1 Answer 1

4

There isn't anything like this available in SwiftUI's APIs so far afaik. Make sure to open an enhancement request with Apple.

Implementing "navigation" on your own is a terrible idea, as you basically give all the accessibility and facility support afforded by UINavigationController.

Instead, here is a suggestion:

Either by means of a custom SwiftUI view or modifier, wrap the NavigationView with a UIViewControllerRepresentable wrapper, which in turn sets up a UIHostingController subclass, which waits for addChild(_:) to be called, which will be the navigation controller added as a child of the hosting controller. From here, if your animations are "static" (e.g. do not require any subview to subview transition), you can accomplish this here by implementing the navigation controller delegate, and providing the animation controller.

If you do need more evolved transitions (such as Photos.app's photo transition), you can create a custom UIViewRepresentable wrapper, which will serve as markers for "from" views and "to" views, you can then use those discover in UIKit, and e.g. can snapshot and animate in transitions.

Proposed API can look like this:

struct ContentView1: View {
    var body: some View {
        NavigationLink(destination: DetailView()) {
            Image("small").customSourceTarget()
        }.navigationBarTitle("Navigation")  
    }
}

struct ContentView2: View {
    var body: some View {
        Image("large").customTransitionTarget()
    }
}

NavigationView {
    ContentView1()
}.customAnimatable()
Sign up to request clarification or add additional context in comments.

2 Comments

"wrap the NavigationView with a UIViewControllerRepresentable wrapper" - what do you mean? Could you please show an example?
@chudin26 What exactly is unclear in what I wrote? If you are not familiar with UIViewControllerRepresentable, you can read Apple’s docs, as well as the documentation of UIViewController’s child/container lifecycle.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.