Closed andrebraga closed 8 years ago
In what cases removing IB-generated constraints in awakeFromNib
is not enough?
TL;DR: try inserting views dynamically to a layout initially defined on IB. Or changing label contents.
Long version:
It's more complicated than that. At awakeFromNib time the view's frame is not final yet, and it it will receive size constraints by the time its superview is awake(n)FromNib.
It usually won't hurt if your layout contents is essentially static and defined by the storyboard, but if you mix IB and code to dynamically insert arranged subviews the whole layout will break. Likewise for labels whose content is set at run time, by receiving autogenerated sizing constraints they will end up truncating the content.
I have a grid-like layout with passenger type (adult, child, infant) on the left, horizontal hugging priority @249, vertical axis, centre aligned; and ticket fares on the right, default hugging, again vertical and centered. Layout defaults is the amount of adults.
So it's top level Horizontal Stack, fill & centre; 2 Vertical Stack, fill & centre Left one has labels, H-hugging @249 Right one has labels, defaults
I insert labels corresponding to the other two cases dynamically. The layout will break right at that moment because, say, the left vertical stack received an autogenerated height constraint. Or some label on the right received text larger than what was laid out on IB.
The way I did it was the only way I could reliably remove all autogen constraints. Removing from subviews is necessary so the labels don't truncate their contents, and I was not too fond of removing them from the superview as well but one can't control when IB will inject positioning constraints in addition to sizing.
Was this - long - explanation clear at all? Perhaps I should create a test case to demonstrate the issues I found?
I didn't reproduce your problem. But I think there is some problems in my code. I only remove IB generated constraints that are added to the stack view, but maybe there are also some IB generated constraints added on the subviews (e.g. width and height constraints of the subview). I think removing that kind of constraints can fix the problem. Did you try that?
That's quite exactly what my PR does. =)
Perhaps this will help. Try adding labels below the first one that says "Label". I extracted the relevant part to a XIB and marked the relevant StackView; I think it will suffice to test. I don't have a lot of time right now to polish it and make a test case project, maybe tomorrow or Monday at most.
This layout is quite complicated. I have a lot of "missing constraints" errors in Interface Builder. Is this also the case in your project?
Well, of course, since the constraints that IB considers missing are the very ones created by TZStackView... After building and refreshing the views on IB you'll notice it stops complaining about constraints though.
Still a lot of errors after refreshing all views. How do you determine the size of the top level view?
That one should be constrained to a superview, say, the root view of your view controller. The dimensions should be the same as in the XIB, at least in the vertical axis (e.g.: make top vertical spacing and height constraints, and leading and trailing horizontal spacing constraints). Sorry for not creating a proper test project...
One interesting finding: screen orientation change can trigger adding of IB generated constraints.
Nice catch! Which reinforces the need of removing the autogenerated constraints in moments other than awakeFromNib.
Em 28 de fev de 2016, às 12:40, CosynPa notifications@github.com escreveu:
One interesting finding: screen orientation change can trigger adding of IB generated constraints.
— Reply to this email directly or view it on GitHub.
Would you update the commit if you have time?
@andrebraga ?
Sure; the issue is finding time. I'll see what I can manage to do tomorrow. :smile:
Thank you very much for this PR. I'm very glad to see my work is useful to others.
I tried to address your remarks in the most elegant way I could come up with, let me know if you find the patch OK now :smile:
Great. Would you please squash these 3 commits into one?
Squashed! :smile:
IB-generated constraints can sneak in by various means and must be stopped at the addConstraint level. For views we have no control over, be extra zealous and remove them at updateConstraints time (which should happen immediately before the layout pass).
Also fixed removeArrangedSubview not actually removing the subview from the hierarchy.