CosynPa / TZStackView

UIStackView replica for iOS 7.x and iOS 8.x and support Interface Builder
MIT License
4 stars 5 forks source link

IB generated constraints shouldn't even touch StackView-managed views #2

Closed andrebraga closed 8 years ago

andrebraga commented 8 years ago

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.

CosynPa commented 8 years ago

In what cases removing IB-generated constraints in awakeFromNib is not enough?

andrebraga commented 8 years ago

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?

CosynPa commented 8 years ago

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?

andrebraga commented 8 years ago

That's quite exactly what my PR does. =)

andrebraga commented 8 years ago

screenshot

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.

StackTest.xib.zip

CosynPa commented 8 years ago

This layout is quite complicated. I have a lot of "missing constraints" errors in Interface Builder. Is this also the case in your project?

andrebraga commented 8 years ago

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.

CosynPa commented 8 years ago

Still a lot of errors after refreshing all views. How do you determine the size of the top level view?

andrebraga commented 8 years ago

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

CosynPa commented 8 years ago

One interesting finding: screen orientation change can trigger adding of IB generated constraints.

andrebraga commented 8 years ago

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.

CosynPa commented 8 years ago

Would you update the commit if you have time?

CosynPa commented 8 years ago

@andrebraga ?

andrebraga commented 8 years ago

Sure; the issue is finding time. I'll see what I can manage to do tomorrow. :smile:

CosynPa commented 8 years ago

Thank you very much for this PR. I'm very glad to see my work is useful to others.

andrebraga commented 8 years ago

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:

CosynPa commented 8 years ago

Great. Would you please squash these 3 commits into one?

andrebraga commented 8 years ago

Squashed! :smile: