Ever since I am working with preferences (PreferenceKey
,..), I receive this message in the console:
Bound preference _ tried to update multiple times per frame.
After countless times of research, I haven't found any way to silence it. So... since there is yet no question specifically to this warning, what would you think are possible reasons?
If not, can this warning be ignored or did I have to fix it?
Thank you so much!
(I have tried to find an example, but somehow I didn't get any warnings with an easy one...)
SwiftUI’s built-in frame modifier can both be used to assign a static width or height to a given view, or to apply “constraints-like” bounds within which the view can grow or shrink depending on its contents and surroundings. At the very basic level, this is what two common usages of the frame modifier could look like:
As a consequence, no matter which view is actually returned, the result type of the stack will always be the same and hence the compiler won't complain. There is actually a view component SwiftUI provides specifically for this use case and it's actually what stacks use internally as you can see in the example above:
Now SwiftUI will produce some “unspecified and reasonable” results, but will still log a message (“ Contradictory frame constraints specified “), to let you know you did something wrong. So, what does this method do? It positions the view within an invisible frame with the specified width and height constraints.
SwiftUI on macOS has a single modifier to configure our view focus: focusable (). It receives two optional parameters (more on that later). In its default form, by adding this modifier to a view, you are indicating that the view can receive the focus. In AppKit terms we would say it can become the first responder.
The SwiftUI change handlers such as onPreferenceChange
are called on an arbitrary thread. So if these changes impact your View, you should re-dispatch to ensure that you make those updates on the main thread:
.onPreferenceChange(MyPreferenceKey.self) { newValue in
DispatchQueue.main.async {
widget.value = newValue
}
}
I think this answer from an Apple engineer describes the general issue:
It sounds like you have a cycle in your updates. For example, a GeometryReader that writes a preference, that causes the containing view to resize, which causes the GeometryReader to write the preference again. It’s important to avoid creating such cycles. Often that can be done by moving the GeometryReader higher in the view hierarchy so that its size doesn’t change and it can communicate size to its subviews instead of using a preference. I’m afraid I can’t give any more specific guidance than that without seeing your code, but hopefully, that helps you track down the issue!
https://www.bigmountainstudio.com/community/public/posts/65727-wwdc-2021-questions-answers-from-slack-the-unofficial-archive
At least it inspired me to solve the related bug in my case and make the warnings go away (almost :)).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With