Open djblake opened 6 years ago
I do not understand what you want to express If you are so tangled, do not use automationManagesSubnodes, forcing yourself to manage nodes
My apologies, I will explain better.
What I am demonstrating is there a bug in the layout diffing algorithm when using automaticallyManageSubnodes. Presumably when someone calls setNeedsLayout, it calls layoutSpecThatFits:, and then compares the layoutSpec that was returned to the current one, analyses the differences between these, and then animates the changes. I am showing that in a certain situation, it fails to analyse the difference between two layouts.
The help bring some context to this issue, I will describe the project I am working on as an example.
In my project, I have an ASCellNode. This cell has a subnode 'Container' class added to it, which allows for dynamic content to be added to it. For example if a user was posting text, it would be the 'textContainer' subclass, if they were posting an image, the 'imageContainer' subclass. When its the imageContainer subclass, the heirarchy looks like this:
[ ASCellNode
[imageContainer
[image A]
]
]
Suppose I want to change the image displayed to be a different image. I could have a BOOL flag which controls if image A or image B is shown. To update I could simply check the BOOL flag in layoutSpecThatFits: and add either image A or image B into the hierarchy when setNeedsLayout is called. Except this is where the bug lies. If image A and image B are the same dimensions, then the diffing algorithm will think they are the same and the layout will not actually get updated. You have to make the two images at least 1 pixel different for the setNeedsLayout to actually have an effect. This is that 'second' issue I mentioned originally above.
The third issue is something I came across whilst trying to work out what causes the second one. If the imageContainer has a 'minHeight' property set, and the height of image A or image B is the same as this minHeight or lower, then setNeedsDisplay will also fail to update. Presumably this is because image A and B are both forced to be the minHeight of their parent, making them both the same height, and thus failing to be determined to be different by the layout diffing bug.
I am not tangled - I understand the issues and how to avoid them, in my project I am just forcing the dimensions to be 1 point different when I call setNeedsLayout to avoid this issue. But I was asked to create an issue/example project for this bug so I did.
Upon further reflection on this issue, I have realised the issue is caused because the diffing algorithm does not presumably check subnodes recursively. Setting a 1 point different on image A vs image B causes the imageContainer parent to be a different height than it was before, and it is this difference that it is detecting has changed between the layouts, rather than image A vs image B changing size. I'm betting you could theoretically have both image A and image B appear simultaneously stacked next to each other, and as long as the sum of their dimensions does not change (ie [image A width = 20][image B width = 80] = 100 vs [image A width = 60][image B width = 40] = 100 ) it would not detect a difference.
The solution to this then would be to call setNeedsLayout directly on node that has changed - in my case the imageContainer node, rather that on its parent ASCellNode. I have just tried implementing this in my code and can confirm it works properly without the workaround setting the dimension difference.
Whether then if this is a bug or it is just an unavoidable consequence of not being able to call the diffing algorithm on subnodes recursively for performance reasons I will leave to someone with more experience!
I have recently encountered some issues with ASCellNodes not updating properly when I believe they should, and created a simple example project which demonstrates these issues.
The first issue shows what happens if you try to add a subNode of an ASCellNode to a separate layer without properly removing it first (can no longer update the ASCellNode)
The second issue shows what happens if you update a sub node of an ASCellNode with a different ASDisplayNode of the same dimensions (setNeedsLayout has no effect).
The third issue shows what happens if a sub-sub-node of an ASCellNode is the same size as its parent node's minHeight (setNeedsLayout has no effect).
I have attached an example project showing these below:
TextureLayoutDifBug.zip
At the top of the 'ViewController' class I have described the steps to go through to observe each bug. The same text also pasted below here:
_
_