Best practice for swapping views with auto layout

Hi all,


I've been using auto layout but I'm not an expert yet. I always have this question that I'm not sure of the answer. Please share your thoughts.


Obviously, when you write an app, you can't just put every view in the interface build and then add constraints to them all. There're views that being dynamically generated at run time and "addSubView". What I've been doing is add static views & constraints, then add dynamic views at run time and programatically add constraints to them and hide static views as needed. Is there any other way of doing things like this?


For example: I have a UIButton in the beginning. The user can tap on it and it'll slide to the left (and still visible) to show 3 additional UILabels (to the right of the button). I obviously need to programatically add constraints to the new labels. Then the user can tap on the same button again and it'll slide back to its original position and the 3 labels are removed.


Is there a better way than just manually adding/removing constraints so that static and dynamic views can work together in harmony? 😢


Thanks all.

Apple recommends using NSStackView to organize such layouts. With a stack view, you just add and remove the views you want and the stack view handles the constraints. Mind you, the recommendation was part of the introduction to the new features of NSStackView added in OS X 10.11. So, you may find yourself missing some of that new functionality if you have to deploy to current releases.

@Ken


Yeah, I have to support iOS8, so NSStackView is not an option....

Well, there are various approaches that can maybe make things easier.


For example, you could have all of the buttons showing in IB, with the appropriate constraints for the "expanded" case. Keep (strong) outlets for the constraints that would have to be deactivated in the "collapsed" case. At view load, deactivate those constraints because "collapsed" should be the initial state. When the button is clicked to expand, reactivate them. (You don't have to add and remove them to/from a specific view. See the active property and +[NSLayoutConstraint activateConstraints:], etc.)


In the collapsed state, when those initial constraints are disabled, you still need some other constraint to put the remaining button at its appopriate position (toward the right). You can either create the constraint on demand and activate and deactivate it as appropriate or you can try to come up with a permanent constraint that automatically compensates for the change in the others. For example, you can have a constraint that the button's trailing edge is some small distance from the superview's trailing edge (or margin), but make its priority lower than the priorities of the constraints involving the other buttons in the expanded state. Be sure to keep it lower than the compression resistance of those other buttons, too, so it doesn't squish them. So, when those other constraints are active, the button will be pushed further away from the edge than it "wants" to be. When they are inactive, it can be in its desired position.


Unfortunately, this sort of approach needs to be custom designed for each specific scenario with dynamic views. I don't know if I can give you a good approach that works in the general case.

Best practice for swapping views with auto layout
 
 
Q