How to hide background of matchedTransitionSource?

How to hide background of matchedTransitionSource?

How can I hide the background of an animated NavigationLink while using the swipe-to-go-back gesture? Here's what I currently have:
animation #1
and what I want it to look like:
animation #2
similar to the iOS Photos app. I'm okay with covering the background using a solid color or a heavy blur, but I don't want it to be visible during the transition.

struct ContentView: View {
    @Namespace private var transitionNamespace
    var body: some View {
        NavigationStack {
            VStack {
                Text("Should not be visible while swiping")

                let value = "details"
                NavigationLink(value: value) {
                    Text("Link")
                        .frame(width: 200, height: 50)
                        .background(Color.green.opacity(0.5))
                        .clipShape(RoundedRectangle(cornerRadius: 32))
                        .matchedTransitionSource(id: value, in: transitionNamespace)
                }
            }
            .navigationDestination(for: String.self) { value in
                ZStack {
                    Color.yellow.ignoresSafeArea(.all)
                    Text(value)
                }
                .navigationTransition(.zoom(sourceID: value, in: transitionNamespace))
                .navigationBarBackButtonHidden(true)
            }
        }
    }
}

Answer

You could try using a state variable to record whether to apply a blur or not. The state variable can be updated in the .onDisappear callbacks of the NavigationLink and its destination:

@State private var isBlurred = false
NavigationStack {
    VStack {
        Text("Should not be visible while swiping")

        let value = "details"
        NavigationLink(value: value) {
            Text("Link")
                .frame(width: 200, height: 50)
                .background(Color.green.opacity(0.5))
                .clipShape(RoundedRectangle(cornerRadius: 32))
                .matchedTransitionSource(id: value, in: transitionNamespace)
        }
        .onDisappear { isBlurred = true } // 👈 added
    }
    .blur(radius: isBlurred ? 10 : 0) // 👈 added
    .navigationDestination(for: String.self) { value in
        ZStack {
            Color.yellow.ignoresSafeArea(.all)
            Text(value)
        }
        .navigationTransition(.zoom(sourceID: value, in: transitionNamespace))
        .navigationBarBackButtonHidden(true)
        .onDisappear { isBlurred = false } // 👈 added
    }
}

Animation

Enjoyed this article?

Check out more content on our blog or follow us on social media.

Browse more articles