YogaKit doesn't remember the origin of the root view. #378
Reference in New Issue
Block a user
No description provided.
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Report
When you apply layout to a root view of layout with an origin that is not
CGPointZero
, in some scenarios it seems that this would be the incorrect behavior.Issues and Steps to Reproduce
YogaKit
directory and runpod install
.Expected Behavior
The bordered view should stay on screen (ideally).
Actual Behavior
The bordered view's .frame.origin is set to (0,0).
cc @hartbit Have you run into this? I'm trying to decide if there is a better way to fix this, other than requiring users to manually set the inset on a yoga view.
@dshahidehpour does this problem persist if you use some thing different than
space-around
on the root node? My theory is that on the second click the root height is diffierent/bigger. And so you position the blue square at a lower position/centered.@woehrl01 let me spit out some debug info for you.
Here's the output when the screen loads (before I hit the button):
Here's the output when I tap the button (and the root view shifts):
So yeah it looks like the computed height is changing from 736 to 672.
I guess I'm surprised that simply recalculating the layout of the root view without making any changes to the
YGNodeRef
causes the view to change it's height.@dshahidehpour not sure, as I'm not that familiar with YogaKit, but as the difference is 64, this looks to me like the height of the button which isn't explicitly set. I experienced on other ui frameworks, that the height is sometimes only predictable after the ui has been visible the first time. Do you have the same problem if you set the buttons height to a fixed value?
@dshahidehpour Sounds weird to me. I don't have time to check it out this evening, I want to get the percentage value PR posted, but have you tried nailing down the problem to the button's
sizeThatFits
returning different values?@woehrl01, @hartbit It's not the button. When I hit the "reapply layout" button, it's not trying to remeasure the button.
Here's my debug:
Notice that when I tap the button, it's not remeasuring that node.
So here's the problem:
The frame of the my rootView is
{.origin = {0, 64}, .size = {414, 672}}
. When I reapply the layout, we only pass in the size{414, 672}
. As a result, when it computes the layout, it had no idea that the rootView's origin was set outside of YogaKit, so it sets the new frame to{0, 0, 414, 672}
.I'm thinking that we should add some functionality so that we can choose to preserve the origin of the root of layout. I'll put up a PR for this.
@dshahidehpour Oh, I see! It overrides the predefined position. Couldn't this be solved by setting the root view with
top: 64
(yoga) ?@woehrl01 Yeahp, that would solve it. Another way is to create a "wrapper" view that goes inside the root view. Then suddenly the coordinate frame of the wrapper view has no idea the rootView has a predefined offset.
I'm also thinking about updating the
applyLayout()
function so that it takes a parameter that allows you apply the predefined origin to the root. What do you think about @hartbit?Is there a case where we do NOT want it to preserve the root view's origin? It might be better to fix it by always preserving the origin.
I can't think of a use-case at the moment. I'll put up a PR, and we can see what happens.
Diff coming, I'm going to close this.
@dshahidehpour I looked at your diff and it seems like if you now set top via yoga, you will move it down every time you call applyLayout. As we add the position to the previous position.
@woehrl01 That's totally true. That being said there are ways around fixing that (just like there were for the original problem). Overall, I felt like this behavior will solve the most amount of bugs on iOS pertaining to root views on iOS. But if seems to persist as a problem, I'll definitely revisit it.
@dshahidehpour maybe we should add a comment to
applyLayout
which documents this?I was also thinking of making the preservation optional
OR
Swift could be
view.yoga.applyLayout(preverseOrigin: true)
;I'd prefer the first, it's the most descriptive one and not shorter than the swift version, but also applies to obj-c.
[view.yoga applyLayoutPreservingOrigin:YES];
view.yoga.applyLayout(preservingOrigin: true)
If you want to follow Swift naming conventions by making it more grammatically correct.