NO ANIMATIONS in NavigationStack or NavigationSplitView

I'm building a macOS app using SwiftUI and I recently updated to xcode 14.3. Since then I've been debugging why none of my animations were working, it turned out that the NavigationSplitView or NavigationStack are somehow interfering with all the animations from withAnimation to .transition() and everything in between.

Is anyone else experiencing this, knows a work around or knows why this is happening?

Accepted Reply

We are aware of this. This is an internal bug. My sincere apologies for this particular one.

Can you let me know if this workaround works for you? Pass an animated path binding to your NavigationStack's path parameter. If you aren't using the path parameter, you should be able to simply pass a NavigationPath value to the stack's initializer and all will behave the same.

struct ContentView: View {
    @State private var path = NavigationPath()
    @State private var isOn = false

    var body: some View {
        NavigationStack(path: $path.animation(.linear(duration: 0))) {
            VStack {
                Toggle("Animate Square?", isOn: $isOn.animation(.linear(duration: 3)))
            Color.red
                .frame(width: 100, height: 100, alignment: .bottom)
                .scaleEffect(isOn ? 1.0 : 0.5)
                NavigationLink("Faux non-animated push", value: 3)
            }
            .navigationDestination(for: Int.self) { _ in
                Color.orange
            }
            .toolbar { Spacer() }
        }
    }
}

In the code below, notice how I pass a duration of 0 to the $path.animation(.linear(0)). This achieves a non-nil animation, but doesn't force adoption of animated pushes if you don't want them. The workaround is providing that animation to the path. The bug erroneously disabled all animations when a stack animation wasn't provided. (Rest assured we now have tests for this, and sorry again for the inconvenience)

  • Thanks so much for your quick response, this solution 100% works 🙏 drove me crazy for a couple days debugging this 🫠

  • Issue doesn't persist anymore with iOS 17.0 Xcode 15.0

  • Issue still exists on macOS 14 (sonoma) with NavigationSplitView and NavigationStack in the detail column.

Replies

We are aware of this. This is an internal bug. My sincere apologies for this particular one.

Can you let me know if this workaround works for you? Pass an animated path binding to your NavigationStack's path parameter. If you aren't using the path parameter, you should be able to simply pass a NavigationPath value to the stack's initializer and all will behave the same.

struct ContentView: View {
    @State private var path = NavigationPath()
    @State private var isOn = false

    var body: some View {
        NavigationStack(path: $path.animation(.linear(duration: 0))) {
            VStack {
                Toggle("Animate Square?", isOn: $isOn.animation(.linear(duration: 3)))
            Color.red
                .frame(width: 100, height: 100, alignment: .bottom)
                .scaleEffect(isOn ? 1.0 : 0.5)
                NavigationLink("Faux non-animated push", value: 3)
            }
            .navigationDestination(for: Int.self) { _ in
                Color.orange
            }
            .toolbar { Spacer() }
        }
    }
}

In the code below, notice how I pass a duration of 0 to the $path.animation(.linear(0)). This achieves a non-nil animation, but doesn't force adoption of animated pushes if you don't want them. The workaround is providing that animation to the path. The bug erroneously disabled all animations when a stack animation wasn't provided. (Rest assured we now have tests for this, and sorry again for the inconvenience)

  • Thanks so much for your quick response, this solution 100% works 🙏 drove me crazy for a couple days debugging this 🫠

  • Issue doesn't persist anymore with iOS 17.0 Xcode 15.0

  • Issue still exists on macOS 14 (sonoma) with NavigationSplitView and NavigationStack in the detail column.

If you are using NavigationSplitView without stacks, unfortunately, you'll need to use the same workaround above. Which effectively means shimming a NavigationStack as the root of the column in which you want the animations, and then structuring your NavigationLinks such that they aren't targeting the stack.

What is ETA on the fix for this, this workaround doesn't work 100% of the time for me.

I am having the same problem with NavigationSplitView, I don't quite understand your fix proposal. When do you see this fix getting released, if it's not long I'd rather move on.

Same issue on iOS16 with NavigationStack nested in a Paging style tab view

I am running iOS17 with Xcode 15.0.1 and just ran into this bug I believe. I followed your work around and the animation returned. Was this supposed to be fixed with iOS17 and 15.0.1?

I copy and pasted the ContentView listen above on mac OS sonoma (14) (XCode 15) and the issue is still there, no animations even by using the animated path.

I NEVER want to see these unwanted animations of the title bar text flying off the screen. Why isn't there an NSDefault option to make sure that the item's unwanted and unasked for extraneous distracting new animations are disabled? And disabled through a standard mechanism such as Defaults.

I want to make sure that the animation in the nav bar is disabled and always so. Seeing items randomly flying off of the screen is a visual distraction that adds unhelpful noise to the UI. It distracts the user. It doesn't help them accomplish their task. This push in the UI team to animate EVERYTHING - whether it serves a useful purpose or not - is taking Apple far away from setting the standard in user interface experiences that HELP the user. There is NO useful purpose that helps the user accomplish their task by having a STATIC user interface element fly off the screen (or fly on the screen for that matter).

It's a distraction - not a helpful aid.

Unwanted and unexpected motion is a VISUAL DISTRACTION to users. ESPECIALLY among UI elements that are static… until they suddenly start flying across the screen.

It serves no purpose at all to help the user accomplish their task and sudden motion actively pulls the user's attention AWAY from what they are trying to focus on. Sudden unexpected motion is bad, startling, distracting and should be actively avoided in productive user interfaces.

For the love of useful interfaces, let us developers - THROUGH A STANDARD MECHANISM - turn OFF this insipid "flying static UI text". No one wants it. No asked for it. It serves no constructive purpose to the user at all.

Now, as developers, how the hell do we turn this unwanted animation OFF in the Navigation title bar?