In SwiftUI, when using the .presentationBackground modifier in combination with the new zoom transitions API, the background does not interpolate or render correctly during or after the transition. This issue is observed when using .fullScreenCover and .sheet with .presentationBackground modifier set for the presenting content.
In the case of using sheet, the modifier does not work at all, and in the case of using .fullScreenCover, the modifier does render the background correctly, but only after a delay.
Sample code:
struct Icon: Identifiable {
var id: String
var color: Color
}
struct ContentView: View {
let icons = [
Icon(id: "figure.badminton", color: .red),
Icon(id: "figure.fencing", color: .orange),
Icon(id: "figure.gymnastics", color: .green),
Icon(id: "figure.indoor.cycle", color: .blue),
Icon(id: "figure.outdoor.cycle", color: .purple),
Icon(id: "figure.rower", color: .indigo),
]
@Namespace var animation
@State private var selected: Icon?
var body: some View {
LazyVGrid(columns: [.init(.adaptive(minimum: 100, maximum: 300))]) {
ForEach(icons) { icon in
Button {
selected = icon
} label: {
Image(systemName: icon.id)
}
.foregroundStyle(icon.color.gradient)
.font(.system(size: 100))
.matchedTransitionSource(id: icon.id, in: animation) { source in
return source.background(Color.clear)
}
}
}
.fullScreenCover(item: $selected, content: { icon in
DestinationView(icon: icon, animation: animation)
.presentationBackground(.thinMaterial)
})
// .sheet(item: $selected) { icon in
// DestinationView(icon: icon, animation: animation)
// .presentationBackground(.ultraThinMaterial)
// }
}
}
struct DestinationView: View {
var icon: Icon
var animation: Namespace.ID
var body: some View {
Image(systemName: icon.id)
.font(.system(size: 300))
.foregroundStyle(icon.color.gradient)
.navigationTransition(.zoom(sourceID: icon.id, in: animation))
}
}
#Preview {
ContentView()
}
I have filed a feedback regarding this issue: FB14929113 but if there are any workarounds out there at the moment, I'd love to know. Thanks!