Why does ForEach initialize its Child View twice as much in SwiftUI?

I came across a weird behaviour of SwiftUI's ForEach view.

I've noticed that ForEach always initialize its child view twice as much according to its repetition. Normally when you render the view, its init is called once. But if you put the view inside ForEach and loop it 4 times, the child view is initialized 8 times instead of 4. Is this a desired behavour or am I missing something?

tested on: Xcode 14.0.1, iOS 16, simulator iPhone 13 Pro (with iOS 16)

I am grateful for any feedback!

struct ContentView: View {
    
    var body: some View {
        VStack {
            // Note that ForEach is looped 4 times!
            ForEach(0..<4, id: \.self) { _ in
                CustomView() // -> this view is initialized 8 times instead of 4.
            }
        }
    }
}

struct CustomView: View {

    // custom initializer with print to check how many times this view is initialized in log output
    init() {
        print("CustomView initialized")
    }
    
    var body: some View {
        Text("Some Custom View")
    }
}

That's apparently some old bug (with probably no harm, but that depends on what you do in init ): https://stackoverflow.com/questions/61528757/why-does-this-swiftui-view-init-twice

You may read this to get an inner view of how init() works in SwiftUI. https://stackoverflow.com/questions/68633861/swiftui-view-init-called-multiple-times

I encountered the same issue introduced with iOS 16. For me its resulting in duplicated Views, so instead of 4 Views 8 Views are displayed. Same code worked without any issues on iOS 15.

I encountered this problem for a LazyVStack. My solution worked for me.

Once you determine that the ForEach is called twice, use some debugging to determine where and why the view may be re-rending twice. Sometimes swift may re-render a view and in this case the ForEach may appear twice inside the VStack, as ForEach acts as its own Collection for views. https://developer.apple.com/documentation/swiftui/foreach

As for the debugging part, try putting a .onAppear( //print something and add a break point ){} on the ForEach (Tested), if it is called twice you know that it is re-rendered twice.

1 - see the changes that occur between the first break point and the second break point to see the changes

I hope this can help someone else that experiences the same issue.

Why does ForEach initialize its Child View twice as much in SwiftUI?
 
 
Q