Preference tried to update multiple times (SwiftUI)

I measure the child view size and pass it to the parent view using preference technic. Time by time I get the next message in console Bound preference WidthKey tried to update multiple times per frame.
Nothing happens in terms of errors or an unexpected behaviour.

Do I need bother about this massage or it's just information that it happens ?

Xcode Version 12.5 beta 3

Preference case 1 video
Preference case 2 video
Preference case 3 video
Preference case 4 video

It might be better to ask questions about SwiftUI over Apple Developer Forums.

Thank you

Now, AFAICT, GeometryReader is updating, causing WidthKey to be written, which in turn refreshes GeometryReader. GeometryReader always takes all available offered space, so that might not be necessary if you're trying to match the view sizes.

You should include your actual code so people can try it out and see. Your code don't seem to match the preview: the red background on "Text" has padding around it. But the code doesn't have .padding()

I type in your code running it in Xcode Version 12.5 beta 3 (12E5244e) both in preview or simulator don't show the "...multiple time per frame" message:

Edit: I added print in .onPreferenceChange(...), only one print out once. And on editing, only once per keystroke. Seems to work fine for iPhone. Run in iPad simulator show something else:

"... Unable to simultaneously satisfy constraints ..."

import SwiftUI

struct ContentView: View {
    @State private var width: CGFloat? = nil
    @State var yourText = "Text"


    var body: some View {
        VStack(spacing: 0) {
            TextField("Text", text: $yourText)
            Spacer()
            Color.yellow
                .overlay(
                    Text("\(yourText)")
                        .background(
                            GeometryReader { proxy in
                                Color.clear.preference(key: WidthKey.self, value: proxy.size.width)
                            }
                            .background(Color.red)
                        )
                    , alignment: .center)
                .onPreferenceChange(WidthKey.self) { print("onPC() called!"); width = $0 }
        }.frame(alignment: .center)
        .background(Color.green)
    }
}


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

private struct WidthKey: PreferenceKey {
    static let defaultValue: CGFloat? = nil
    static func reduce(value: inout CGFloat?, nextValue: () -> CGFloat?) {
        value = value ?? nextValue()
    }
}

Sorry for not including the code

I simplified the example and every time I managed to reproduce the "Bound preference tried to update multiple times..." in diff conditions

Preference case 1 video
Preference case 2 video
Preference case 3 video
Preference case 4 video

import SwiftUI

struct ContentView: View {
    
    @State var width: CGFloat? = nil
    @State var myText : String = "Text"
    
    var body: some View {
        VStack{
        TextField("Mytext", text: $myText)
        Spacer()
        Text("\(myText)")
                .background(
                    GeometryReader{ proxy in
                        Color.clear.preference(key: WidthKey.self, value: proxy.size.width)
                    }
                )
            .fixedSize()
            .frame(width: 200, height: 200)
            .onPreferenceChange(WidthKey.self){self.width = $0 }
        }
    }
}

struct WidthKey: PreferenceKey {
    static var defaultValue: CGFloat? = nil
    static func reduce(value: inout CGFloat?, nextValue: () -> CGFloat?) {
        value = value ?? nextValue()
    }
}

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

Bound preference tried to update multiple times per frame

http://www.openradar.appspot.com/FB7558683

Terms of Service

Privacy Policy

Cookie Policy