Adeline
Adeline

Reputation: 475

keeping constraints when replacing a view by an other view

In my application, I have :

When the app loads, I am using :

initWithNibName:nibName andReplaceView:(the custom view) resize:YES

To replace the custom view. I know there is an option placeholder for the views in IB, but I do not know how to use it, and my app works well this way... ... except that the loaded view does not inherit the layout constraints of the replaced view.

How can I fix this ?

Edit: Sorry, I forgot that the function was mine... I wrote it a long time ago in a category. Here is the code :

- (id)initWithNibName:(NSString*)nibName andReplaceView:(NSView*)aView resize:(BOOL)resize
{
    // 1. Loading the bundle
    if (self = [self initWithNibName:nibName bundle:nil])
    {
        [self replaceView:aView resize:resize]; 
    }

    return self;    
}

- (void)replaceView:(NSView*)aView resize:(BOOL)resize
{
    if (resize)
    {
        NSRect insertionFrame = [aView frame];
        [[self view] setFrame:insertionFrame];
    }
    else
    {
        NSRect insertionFrame = [aView frame];
        insertionFrame.size.width = [[self view] frame].size.width;
        insertionFrame.size.height = [[self view] frame].size.height;

        [[self view] setFrame:insertionFrame];
    }

    NSView* supView = [aView superview];
    [supView replaceSubview:aView with:[self view]];
}

Upvotes: 0

Views: 222

Answers (1)

Tom Dalling
Tom Dalling

Reputation: 24145

When you replace a view, it removes all the layout constraints attached to the old view.

Personally, I just put the new view inside the old view. Here is some code I've used:

@implementation SJPlaceholderView

-(void) fillWithView:(NSView*)view {
    NSParameterAssert(view);

    view.frame = self.bounds;
    [view setTranslatesAutoresizingMaskIntoConstraints:NO];

    [self addSubview:view];

    [self addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"H:|[view]|"
                                             options:0
                                             metrics:nil
                                               views:NSDictionaryOfVariableBindings(view)]];

    [self addConstraints:
     [NSLayoutConstraint constraintsWithVisualFormat:@"V:|[view]|"
                                             options:0
                                             metrics:nil
                                               views:NSDictionaryOfVariableBindings(view)]];
}

@end

This makes sure the inner view frame matches the outer view frame exactly. All the layout constraints on the outer view are still in effect.

You could also try to loop through all the constraints of the old view, and apply them to the new view. Most of the constraints will be on the view itself, or the superview, but they could theoretically be on any of the ancestor views.

Upvotes: 1

Related Questions