Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SwiftUI | Warning: Bound preference _ tried to update multiple times per frame. Possible reasons?

Tags:

ios

swiftui

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...)

like image 832
Mofawaw Avatar asked Nov 21 '20 09:11

Mofawaw


People also ask

What does the frame modifier do in SwiftUI?

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:

Why does SwiftUI return the same view for every stack?

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:

What does “contradictory frame constraints specified” mean in SwiftUI?

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.

How do I set the focus of a view in SwiftUI?

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.


2 Answers

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
    }
}
like image 99
mbxDev Avatar answered Sep 23 '22 11:09

mbxDev


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 :)).

like image 27
kulich Avatar answered Sep 19 '22 11:09

kulich