Michael Knudsen
Michael Knudsen

Reputation: 629

Aligning NSViews Using Autolayout Programmatically

I am having troubles aligning NSViews next to each other using Autolayout programmatically. To illustrate, I have made a very simple example project. DiscView is a subclass of NSView which draws a disc with a specified color.

In the example below, I only add Autolayout constraints on one of two subviews, and the result is as I expected (see screenshot below).

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    DiscView *discViewA = [[DiscView alloc] init];
    DiscView *discViewB = [[DiscView alloc] init];

    discViewA.color = [NSColor blackColor];
    discViewB.color = [NSColor redColor];

    discViewA.translatesAutoresizingMaskIntoConstraints = NO;
    discViewB.translatesAutoresizingMaskIntoConstraints = NO;

    [self.customView addSubview:discViewA];
    [self.customView addSubview:discViewB];

    NSDictionary *discViewDictionary = @{@"discViewA" : discViewA,
                                         @"discViewB" : discViewB};

    [self.customView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[discViewA]|" options:0
                                                                           metrics:nil
                                                                              views:discViewDictionary]];

    [self.customView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[discViewA]|" options:0
                                                                            metrics:nil
                                                                              views:discViewDictionary]];
}

enter image description here

However, if I try to show the two subviews side by side using some additional constraints, I only see a red disc. That is, it is as if the red disc is drawn directly on top of the black disc.

[self.customView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[discViewA]-[discViewB]|" options:0
                                                                               metrics:nil
                                                                                  views:discViewDictionary]];

[self.customView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[discViewA]|" options:0
                                                                                metrics:nil
                                                                                  views:discViewDictionary]];

[self.customView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[discViewB]|" options:0
                                                                                metrics:nil
                                                                                  views:discViewDictionary]];

enter image description here

What could possibly be wrong here?

Upvotes: 0

Views: 636

Answers (2)

GregP
GregP

Reputation: 1624

[self.customView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[discViewA][discViewB]|" 
                                                                        options:NSLayoutFormatAlignAllTop | NSLayoutFormatAlignAllBottom 
                                                                          views:discViewDictionary]];


[self.customView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[discViewA]|" options:0
                                                                        metrics:nil
                                                                          views:discViewDictionary]];

Try this. It might help. If not do what someone else suggest and put a constraint like so.

[self.customView addConstraint:[NSLayoutConstraint constraintWithItem:discViewA
                                                                attribute:NSLayoutAttributeWidth
                                                                relatedBy:NSLayoutRelationEqual
                                                                   toItem:self.customView
                                                                attribute:NSLayoutAttributeWidth
                                                               multiplier:0.5f
                                                                 constant:0.f]];

Upvotes: 1

pfandrade
pfandrade

Reputation: 2419

My guess is that when you set both view to be side by side, AutoLayout does not know how to divide the width of the superview between your two views.

Try to add a width constraint to one of those subviews, it should be sufficient to resolve the ambiguity.

Upvotes: 1

Related Questions