shd shd - 6 months ago 22
Objective-C Question

How to add two views on each other with constraints

I am trying to add 2 views with same X, Y. They have space from the edge using

addConstraints:[NSLayoutConstraint constraintsWithVisualFormat...]


I tried the strings
"H:|20-[A][B]-20-[C]-20-[D]-20|"
and
V:|20-[A][B]-20-[C]-20-[D]-20|
, and
centreX == CenterX
and
centerY==centerY
, but they kept conflicting, thinking that A and B should be next to each other.

A is hidden, and on some button clicked, B is hidden and A is shown.

Answer

To add views with same centre X,Y You need to first place one of the view say bView (Bottom view), using constatins

NSArray * bVerticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-20-[bView]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(bView)];
    NSArray * bHorizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[bView]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(bView)];

This places the bView in the superview with 20 as edge offset.

Now place the tView (top View) with same centre as of bView. Here self is the superview of bView and tView

[self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[bView]-(<=1)-[tView]" options:NSLayoutFormatAlignAllCenterX metrics:nil views:NSDictionaryOfVariableBindings(bView,tView)]];
    [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[bView]-(<=1)-[tView]" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(bView,tView)]];

Then pin the edges of tView with desired offset say 40

NSArray * tVerticalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|-40-[tView]-40-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(tView)];
    NSArray * tHorizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-40-[tView]-40-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(tView)];

EDIT :

Here is how do do it.

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    bView = [UIView new];
    bView.backgroundColor = [UIColor redColor];
    bView.translatesAutoresizingMaskIntoConstraints = NO;

    tView = [UIView new];
    tView.backgroundColor = [UIColor blackColor];
    tView.translatesAutoresizingMaskIntoConstraints = NO;

    // Firdt bView is added then tView hence tView is exaclty above the bView.
    [self.view addSubview:bView];
    [self.view addSubview:tView];


    // Edges Constrints for bView
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-20-[bView]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(bView)]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[bView]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(bView)]];

    // Edges Constints for tView
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|-20-[tView]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(tView)]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[tView]-20-|" options:0 metrics:nil views:NSDictionaryOfVariableBindings(tView)]];

    // Centring for bView and tView
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[bView]-(<=1)-[tView]" options:NSLayoutFormatAlignAllCenterX metrics:nil views:NSDictionaryOfVariableBindings(bView,tView)]];
    [self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[bView]-(<=1)-[tView]" options:NSLayoutFormatAlignAllCenterY metrics:nil views:NSDictionaryOfVariableBindings(bView,tView)]];

}

-(IBAction)toggleViews:(id)sender {
    NSArray * subViews = self.view.subviews;
    [self.view exchangeSubviewAtIndex:[subViews indexOfObject:tView] withSubviewAtIndex:[subViews indexOfObject:bView]];
}