Matt
Matt

Reputation: 395

NSLayoutConstraints conflicts

I'm trying to add buttons programmatically to a view below an NSTextField that is already in the view. The view was created in IB and uses constraints. It is an NSTableCellView, but I doubt that makes any difference in this case. My code is thus:

NSView *previousView = self.pathsField;

for( NSString *path in self.revision.paths )
{
    NSButton *pb = [[NSButton alloc] initWithFrame: bframe];

    pb.bezelStyle = NSRoundRectBezelStyle;
    [self addSubview: pb];
    pb.title = path;
    [self addConstraint: [NSLayoutConstraint constraintWithItem: pb
                                           attribute: NSLayoutAttributeTop
                                           relatedBy: NSLayoutRelationEqual
                                           toItem: previousView
                                           attribute: NSLayoutAttributeBottom
                                           multiplier: 1 constant: 2.0]];
    [buttons addObject: pb];
    bframe.origin.y += 20;
    previousView = pb;
}
self.pathButtons = buttons;

If I take the addConstraint call out the buttons get added with no complaints (just not in the right place). With the addConstraint call I get a lot of messages about constraint conflicts on the debug console and some of my IB created constraints get broken.

Obviously I'm doing something wrong. I expected the constraint to require that the new button's top be 2 px below the bottom of the previous view or button. It doesn't seem like that should cause any conflicts, so where am I off?

Upvotes: 1

Views: 623

Answers (2)

matt
matt

Reputation: 536047

You are actually making both kinds of mistake you can make with constraints: your constraints are both conflicted and ambiguous! Get rid of the conflict by setting translatesAutoresizingMaskIntoConstraints to NO, as someone else has said, but then start worrying about the ambiguity. You can use constraints successfully only if you specify everything needed for layout. You are specifying the top but that's all; you also need to specify the leading edge (left), and probably the width and height too (maybe not because a button sometimes has an intrinsic size; you will have to experiment).

Upvotes: 2

Fruity Geek
Fruity Geek

Reputation: 7381

The errors you are getting are because you have not opted in to autolayout by calling setTranslatesAutoresizingMaskIntoConstraints: on the child views.

NSButton *pb = [[NSButton alloc] initWithFrame: bframe];
[pb setTranslatesAutoresizingMaskIntoConstraints:NO];

Upvotes: 1

Related Questions