Bound preference tried to update multiple times per frame

Originator:pavol.vaskovic
Number:rdar://FB7558683 Date Originated:Jan 31, 2020
Status:Open Resolved:
Product:SwiftUI Framework Product Version:Xcode Version 11.3.1 (11C504)
Classification:bug Reproducible:always
 
Attaching `onPreferenceChange` in certain view configurations causes SwiftUI error: Bound preference CollectionViewSizeKey tried to update multiple times per frame.

In my project this stops the later propagation of Preference Key/Value changes. The issue did occur only when the view with `onPreferenceChange` listener was part of the initial view hierarchy loaded during startup. If this view was loaded later, the issue did not occur. Reducing the bug test revealed the trigger is unrelated to setting a preference on a SwiftUI view, but is caused by mere registration of the `onPreferenceChange` event listener in certain view configurations.

Online search for the error message I was getting returned one case of the same issue, derived from objc.io project collection-view-swiftui. According to comments there, the error message caused nor observable issues in their case. Reducing test case from their example, it appears the common culprit could be the ScrollView?

Issue occurs with Xcode Version 11.3.1 (11C504) in iOS simulator as well as on Device.
Please list the steps you took to reproduce the issue:
1. Run the attached test case in iOS simulator or on device. 
2. Error message appears on console: "Bound preference CollectionViewSizeKey tried to update multiple times per frame."

See the two reduced minimal test cases in the attached ContentView.swift (just drop this into empty SwiftUI project):

````
import SwiftUI

struct CollectionViewSizeKey: PreferenceKey {
    typealias Value = [CGSize]
    static var defaultValue: [CGSize] { [] }
    static func reduce(value: inout [CGSize], nextValue: () -> [CGSize]) { }
}

// Reduced test case from my project
struct ContentView: View {
    var body: some View {
        NavigationView {
            TabView {
                ScrollView(.horizontal, showsIndicators: false) {
                    Text("Hello, World!")
                }
                .onPreferenceChange(CollectionViewSizeKey.self) {
                    print($0)
                }
            }
            .navigationBarTitle("X", displayMode: .inline)
        }
    }
}


//// Reduced test case from example with same error:
//// https://gist.github.com/Thomvis/cb86cad637e21f5385cd243d4f7a8ad1#gistcomment-3061583
//struct ContentView: View {
//    var body: some View {
//        ScrollView {
//            ForEach(1...1, id: \.self) {
//                Text("\($0)")
//            }
//            .onPreferenceChange(CollectionViewSizeKey.self) {
//                print($0)
//            }
//        }
//    }
//}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
    }
}

````

Comments


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!