Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Removing and re-adding a subview with autolayout

When using autolayout, my understanding is that removing a subview ( while holding a reference to it of course), the removed subview still knows its autolayout constraints.

However, when adding it back to the super view later, the subview no longer knows its frame size. Rather it seems to get a zero frame.

I assumed that autolayout would auto size it to meet the constraints. Is that not the case? I thought auto layout meant don't mess with frame rects. Do I still need to set the initial frame rect when adding the subview, even with auto layout?

like image 344
uchuugaka Avatar asked Jun 21 '13 06:06

uchuugaka


People also ask

Does removing from superview remove constraints?

If the view's superview is not nil , the superview releases the view. Calling this method removes any constraints that refer to the view you are removing, or that refer to any view in the subtree of the view you are removing.

How do you use auto layout to move other views when a view is hidden?

You need to set the compression resistance priority to 0 (not the content hugging) in code when you want to hide the view, and when you want to show again restore that value. Apart of that you need to add a constraint in interface builder to set the size of the view to 0.


1 Answers

When removing the subview, all the constraints that relate to that subview will be lost. If you need to add the subview again later, then you must add constraints to that subview again.

Typically, I create the constraints in my custom subview. For example:

-(void)updateConstraints
{
    if (!_myLayoutConstraints)
    {
        NSMutableArray *constraints = [NSMutableArray array];

       // Create all your constraints here
       [constraints addWhateverConstraints];

       // Save the constraints in an ivar. So that if updateConstraints is called again,
       // we don't try to add them again. That would cause an exception.
       _myLayoutConstraints = [NSArray arrayWithArray:constraints];

       // Add the constraints to myself, the custom subview
       [self addConstraints:_myLayoutConstraints]; 
   }

   [super updateConstraints];
}

updateConstraints will be called automatically by the Autolayout runtime. The code above goes in your custom subclass of UIView.

You're right that in working with Autolayout, you don't want to touch frame sizes. Instead, just update the constraints in updateConstraints. Or, better still, set up the constraints so you don't have to.

See my answer on that topic:

Autolayout UIImageView with programatic re-size not following constraints

You don't need to set the initial frame. If you do use initWithFrame, just set it to CGRectZero. Your constraints will - in fact must - detail either how big something should be, or other relationships that mean the runtime can deduce the size.

For example, if your visual format is: @"|-[myView]-|", that's everything you need for the horizontal dimension. Autolayout will know to size myView to be up to the bounds of the parent superview denoted by |. It's pretty cool.

like image 58
Max MacLeod Avatar answered Sep 22 '22 06:09

Max MacLeod