Zoom transition source tile lags after back navigation when LazyVGrid is scrolled immediately

[Submitted as FB21961572]

When navigating from a tile in a scrolling LazyVGrid to a child view using .navigationTransition(.zoom) and then returning, the source tile can lag behind the rest of the grid if scrolling starts immediately after returning.

The lag becomes more pronounced as tile content gets more complex; in this simplified sample, it can seem subtle, but in production-style tiles (as used in both of my apps), it is clearly visible and noticeable.

This may be related to another issue I recently filed:

CONFIGURATION

  • Platform: iOS Simulator and physical device
  • Navigation APIs: matchedTransitionSource + navigationTransition(.zoom)
  • Container: ScrollView + LazyVGrid
  • Sample project: ZoomTransition (DisappearingTile).zip

REPRO STEPS

  1. Create a new iOS project and replace ContentView with the code below.
  2. Run the app in sim or physical device
  3. Tap any tile in the scrolling grid to navigate to the child view.
  4. Return to the grid (back button or edge swipe).
  5. Immediately scroll the grid.
  6. Watch the tile that was just opened.

EXPECTED

All tiles should move together as one coherent scrolling grid, with no per-item lag or desynchronization.

ACTUAL

The tile that was just opened appears to trail behind neighboring tiles for a short time during immediate scrolling after returning.

MINIMAL CODE SAMPLE

import SwiftUI

struct ContentView: View {
    @Namespace private var namespace

    private let tileCount = 40
    private let columns = [GridItem(.adaptive(minimum: 110), spacing: 12)]

    var body: some View {
        NavigationStack {
            ScrollView {
                LazyVGrid(columns: columns, spacing: 12) {
                    ForEach(0..<tileCount, id: \.self) { index in
                        NavigationLink(value: index) {
                            RoundedRectangle(cornerRadius: 16)
                                .fill(color(for: index))
                                .frame(height: 110)
                                .overlay(alignment: .bottomLeading) {
                                    Text("\(index + 1)")
                                        .font(.headline)
                                        .foregroundStyle(.white)
                                        .padding(10)
                                }
                                .matchedTransitionSource(id: index, in: namespace)
                        }
                        .buttonStyle(.plain)
                    }
                }
                .padding(16)
            }
            .navigationTitle("Zoom Transition Grid")
            .navigationSubtitle("Open tile, go back, then scroll immediately")
            .navigationDestination(for: Int.self) { index in
                Rectangle()
                    .fill(color(for: index))
                    .ignoresSafeArea()
                    .navigationTransition(.zoom(sourceID: index, in: namespace))
            }
        }
    }

    private func color(for index: Int) -> Color {
        let hue = Double(index % 20) / 20.0
        return Color(hue: hue, saturation: 0.8, brightness: 0.9)
    }
}

SCREEN RECORDING

Zoom transition source tile lags after back navigation when LazyVGrid is scrolled immediately
 
 
Q