[Submitted as FB20978913]
When using .navigationTransition(.zoom) with a fullScreenCover, deleting the source item from the destination view causes a brief black flash during the dismiss animation. This is only visible in Light mode.
REPRO STEPS
- Build and run the sample code below.
- Set the device to Light mode.
- Tap any row to open its detail view.
- In the detail view, tap Delete.
- Watch the dismiss animation as the list updates.
EXPECTED
The zoom transition should return smoothly to the list with no dark or black flash.
ACTUAL
A visible black flash appears over the deleted row during the collapse animation. It starts black, shortens, and fades out in sync with the row-collapse motion. The flash lasts about five frames and is consistently visible in Light mode.
NOTES
- Occurs only when deleting from the presented detail view.
- Does not occur when deleting directly from the list.
- Does not occur or is not visible in Dark mode.
- Reproducible on both simulator and device.
- Removing .navigationTransition(.zoom) or using .sheet instead of .fullScreenCover avoids the issue.
SYSTEM INFO
- Version 26.1 (17B55)
- iOS 26.1
- Devices: iPhone 17 Pro simulator, iPhone 13 Pro hardware
- Appearance: Light
- Reproducible 100% of the time
SAMPLE CODE
import SwiftUI
struct ContentView: View {
@State private var items = (0..<20).map { Item(id: $0, title: "Item \($0)") }
@State private var selectedItem: Item?
@Namespace private var ns
var body: some View {
NavigationStack {
List {
ForEach(items) { item in
Button {
selectedItem = item
} label: {
HStack {
Text(item.title)
Spacer()
}
.padding(.vertical, 8)
.contentShape(Rectangle())
}
.buttonStyle(.plain)
.matchedTransitionSource(id: item.id, in: ns)
.swipeActions {
Button(role: .destructive) {
delete(item)
} label: {
Label("Delete", systemImage: "trash")
}
}
}
}
.listStyle(.plain)
.navigationTitle("Row Delete Issue")
.navigationSubtitle("In Light mode, tap item then tap Delete to see black flash")
.fullScreenCover(item: $selectedItem) { item in
DetailView(item: item, ns: ns) {
delete(item)
selectedItem = nil
}
}
}
}
private func delete(_ item: Item) {
withAnimation {
items.removeAll { $0.id == item.id }
}
}
}
struct DetailView: View {
let item: Item
let ns: Namespace.ID
let onDelete: () -> Void
@Environment(\.dismiss) private var dismiss
var body: some View {
NavigationStack {
VStack(spacing: 30) {
Text(item.title)
Button("Delete", role: .destructive, action: onDelete)
}
.navigationTitle("Detail")
.toolbar {
Button("Close") { dismiss() }
}
}
.navigationTransition(.zoom(sourceID: item.id, in: ns))
}
}
struct Item: Identifiable, Hashable {
let id: Int
let title: String
}
SCREEN RECORDING