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:
and what I want it to look like:
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
}
}
Enjoyed this article?
Check out more content on our blog or follow us on social media.
Browse more articles