[YogaKit] Removal of element messes up layout #606
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
Issues and Steps to Reproduce
Once you press the button, a label (violet) is added inside the red view:

Once you press the button again, the label gets removed from the red view:

Expected Behavior
State 3 should look exactly like state 1
Actual Behavior
The layout of the state 3 gets messed up. Looks like yoga thinks that the label is still there, also padding gets added twice to the height of the red view.
Link to Code
Demo project is here
Facing this issue, too.
@emilsjolander I'm kinda stumped about this one...
This is the correct layout when the Violet button is inserted.
1.{*wm: LAY_EXACTLY, hm: LAY_EXACTLY, aw: 414.000000 ah: 736.000000 initial
2.{*wm: EXACTLY, hm: AT_MOST, aw: 414.000000 ah: 736.000000 measure
2.}*wm: EXACTLY, hm: AT_MOST, d: (414.000000, 90.000000) measure
2.{wm: EXACTLY, hm: EXACTLY, aw: 414.000000 ah: 90.000000 flex
2.}wm: EXACTLY, hm: EXACTLY, d: (414.000000, 90.000000) flex
2.{[skipped] wm: EXACTLY, hm: EXACTLY, aw: 414.000000 ah: 50.000000 => d: (414.000000, 50.000000) flex
2.{wm: LAY_EXACTLY, hm: LAY_EXACTLY, aw: 414.000000 ah: 90.000000 stretch
3.{*wm: EXACTLY, hm: EXACTLY, aw: 374.000000 ah: 50.000000 flex
3.}*wm: EXACTLY, hm: EXACTLY, d: (374.000000, 50.000000) flex
3.{[skipped] wm: LAY_EXACTLY, hm: LAY_EXACTLY, aw: 374.000000 ah: 50.000000 => d: (374.000000, 50.000000) stretch
2.}wm: LAY_EXACTLY, hm: LAY_EXACTLY, d: (414.000000, 90.000000) stretch
2.{[skipped] wm: LAY_EXACTLY, hm: LAY_EXACTLY, aw: 414.000000 ah: 50.000000 => d: (414.000000, 50.000000) stretch
This is the changes when you remove the violet button. Looks like the container isn't being remeasured.
1.}*wm: LAY_EXACTLY, hm: LAY_EXACTLY, d: (414.000000, 736.000000) initial
Perhaps some dirty flag isn't being set correctly? However I would be very surprised if this is a bug in the C code and not the objc bindings as we aren't facing any similar issues on other platforms.
@kovpas Does the behaviour change if you both call
applyLayout(preservingOrigin: false)
(see thefalse
)@woehrl01 Changing
preserveOrigin: false
doesn't modify the behaviour.@emilsjolander even if I manually mark all the views as dirty it still doesn't change the layout. The curious bit is that this doesn't happen with React Native, which is using the same bindings, right?
This is maybe also related to this issue https://github.com/facebook/yoga/issues/603, which is the reversed problem. Adding an element don't relayout its siblings.
@woehrl01 no, as @tadeuzagallo said, nothing changes if I do
preserveOrigin: false
@lucdion I saw #603... The reason I decided to fill a separate issue is that I don't really think it's related: In the case of #603, the view hierarchy remains the same, only yoga layout hierarchy is changed (by setting
isIncludedInLayout
tofalse
).In my case, view hierarchy changes which leads to the messed up layout.
So, this seems like a UIKit issue. If you set a breakpoint in YGLayout's
YGMeasureView
function you can see that when we callsizeThatFits:
on a plain UIView with no subviews, it is returning a height of 90.That height of 90 + 40 padding (top and bottom, 20) explains the height of 130. It's unclear why UIView is returning 90 as a height. But it makes it clear that it isn't a yoga problem.
@dshahidehpour according to the documentation, this is intended behavior:
I think what happens is that when there's the violet label inside the red view,
sizeThatFits:
gets invoked for this label, and red view's size becomes equal to the label's size. If there are no subviews,UIView
's implementation ofsizeThatFits:
just returnsbounds.size
.Any progress on getting this merged in?