iOS 18 SwiftUI List with animation modifier has unexpected behaviour

Noticed in iOS 18 that List element with animation modifier behaves differently. Seems that on first change of the underlying State property List updates all elements and loses its scroll position even if you insert just one element.

The following code reproduces the behaviour, if you run it on iOS 17 it will behave as expected, you'll see an element being added to the list with an acompanying animation. On iOS 18 you'll lose your scroll position and judging by the animation it seems to update all the other rows in the list even though only one element of the underlaying State property was inserted. After that first update, list element on iOS will behave as expected.

To reproduce the issue scroll down to the ~50th element and tap on a row, compare the behaviour on iOS 17 and iOS 18.

import SwiftUI

struct ContentView: View {
    struct ViewState: Equatable {
        struct Value: Identifiable, Equatable {
            let id: String
            var text: String
            var value: Bool
        }

        let list: [Value]
    }

    @State var viewState: [ViewState.Value] = {
        return (0..<100).map { id in
        ViewState.Value(
            id: "\(id)",
            text: "Row number: \(id + 1)",
            value: Bool.random()
        )
    }}()

    var body: some View {
        list(viewState)
    }

    @ViewBuilder
    private func list(_ list: [ViewState.Value]) -> some View {
        List {
            ForEach(list) { row in
                self.value(row)
            }
        }
        .animation(.default, value: viewState)
    }

    @ViewBuilder
    private func value(_ value: ViewState.Value) -> some View {
        Button(action: {
            guard let rowIndex = viewState.firstIndex(where: { $0.id == value.id }) else {
                return
            }

            viewState.insert(randomValue(id: rowIndex), at: rowIndex + 1)
        }) {
            VStack {
                Text(value.text)
                Text("\(value.value ? "ON" : "OFF")")
                    .foregroundStyle(value.value ? Color.green : Color.red)
            }
        }
    }

    private func randomValue(id: Int) -> ContentView.ViewState.Value {
        let id = (id*100 + 1)
        return .init(id: "New id: \(id)", text: "Row number: \(id)", value: Bool.random())
    }
}

Issues has already been reported using feedback assistant FB16082730

iOS 18 SwiftUI List with animation modifier has unexpected behaviour
 
 
Q