Gergely Kovacs
Gergely Kovacs

Reputation: 1051

Adding Contraints Programmatically

I am trying to achieve the following layout programmatically:

enter image description here

It is a subclassed UIView, on which I would like to place a UILabel with fix height (40 pixels), dynamic width (width is calculated based on the length of the text, so I guess this could be considered fix, not dynamic because I only calculate it one time), and exactly 40 pixels from the left and bottom.

Here is my code:

- (UIView *) initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self)
    {

    marginGeneral       = 40.0f;

    UILabel *titleLabel = [[UILabel alloc] init];
    [titleLabel setTranslatesAutoresizingMaskIntoConstraints: NO];
    titleLabel.backgroundColor  = [UIColor blackColor];
    titleLabel.textColor        = [UIColor whiteColor];
    titleLabel.text             = @"Some Text";
    [self addSubview:titleLabel];

    NSLayoutConstraint *contsTitleLeft = [NSLayoutConstraint
                                          constraintWithItem: titleLabel
                                          attribute: NSLayoutAttributeLeft
                                          relatedBy: NSLayoutRelationEqual
                                          toItem: self
                                          attribute: NSLayoutAttributeLeft
                                          multiplier: 1.0
                                          constant: marginGeneral];

    NSLayoutConstraint *contsTitleRight = [NSLayoutConstraint
                                           constraintWithItem: titleLabel
                                           attribute: NSLayoutAttributeRight
                                           relatedBy: NSLayoutRelationEqual
                                           toItem: self
                                           attribute: NSLayoutAttributeRight
                                           multiplier: 1.0
                                           constant: marginGeneral * -1.0f];

    NSLayoutConstraint *contsTitleBottom = [NSLayoutConstraint
                                            constraintWithItem: titleLabel
                                            attribute: NSLayoutAttributeBottom
                                            relatedBy: NSLayoutRelationEqual
                                            toItem: self
                                            attribute: NSLayoutAttributeBottom
                                            multiplier: 1.0
                                            constant: marginGeneral * -1.0f];

    NSLayoutConstraint *contsTitleHeight = [NSLayoutConstraint
                                            constraintWithItem: titleLabel
                                            attribute: NSLayoutAttributeHeight
                                            relatedBy: NSLayoutRelationEqual
                                            toItem: nil
                                            attribute: NSLayoutAttributeNotAnAttribute
                                            multiplier: 1.0
                                            constant: 40.0f];

    [self addConstraints:@[contsTitleLeft, contsTitleRight, contsTitleBottom]];
    [titleLabel addConstraint:contsTitleHeight];

    }

return self;
}

@end

This of course gives back all kinds of constraint-related warnings and the label does not show up.

Could you nice people help me understand where did I go wrong and how to correct it? Thank you very much!

P.s.: I do not use interface builder, so that is not an option. :)

Upvotes: 0

Views: 65

Answers (1)

Ievgen Leichenko
Ievgen Leichenko

Reputation: 1317

First of all, you never added you titleLabel as subview.

Second, you need to ignore autoresizing masks to avoid conflicts in constraints.

Third, you are adding height constraint to view, whereas it belongs to label.

Here is the code that works:

UILabel *titleLabel = [[UILabel alloc] init];
[titleLabel setTranslatesAutoresizingMaskIntoConstraints: NO];
titleLabel.backgroundColor  = [UIColor blackColor];
titleLabel.textColor        = [UIColor whiteColor];
titleLabel.text             = @"Some Text";
[self.view addSubview: titleLabel];

NSLayoutConstraint *contsTitleLeft = [NSLayoutConstraint
                                      constraintWithItem: titleLabel
                                      attribute: NSLayoutAttributeLeft
                                      relatedBy: NSLayoutRelationEqual
                                      toItem: self
                                      attribute: NSLayoutAttributeLeft
                                      multiplier: 1.0
                                      constant: marginGeneral];

NSLayoutConstraint *contsTitleRight = [NSLayoutConstraint
                                       constraintWithItem: titleLabel
                                       attribute: NSLayoutAttributeRight
                                       relatedBy: NSLayoutRelationEqual
                                       toItem: self
                                       attribute: NSLayoutAttributeRight
                                       multiplier: 1.0
                                       constant: marginGeneral * -1.0f];

NSLayoutConstraint *contsTitleBottom = [NSLayoutConstraint
                                        constraintWithItem: titleLabel
                                        attribute: NSLayoutAttributeBottom
                                        relatedBy: NSLayoutRelationEqual
                                        toItem: self
                                        attribute: NSLayoutAttributeBottom
                                        multiplier: 1.0
                                        constant: marginGeneral * -1.0f];

NSLayoutConstraint *contsTitleHeight = [NSLayoutConstraint
                                        constraintWithItem: titleLabel
                                        attribute: NSLayoutAttributeHeight
                                        relatedBy: NSLayoutRelationEqual
                                        toItem: nil
                                        attribute: NSLayoutAttributeNotAnAttribute
                                        multiplier: 1.0
                                        constant: 40.0f];

[self addConstraints:@[contsTitleLeft, contsTitleRight, contsTitleBottom]];
[titleLabel addConstraint: contsTitleHeight];

UPD: Adding custom view to view controller in viewDidLoad:

CustomView *customView = [[CustomView alloc] initWithFrame: CGRectMake(0, 0, 200, 200)];
[customView setTranslatesAutoresizingMaskIntoConstraints: NO];
[customView setBackgroundColor: [UIColor greenColor]];
[self.view addSubview: customView];

NSLayoutConstraint *widthConstraint = [NSLayoutConstraint constraintWithItem: customView
                                                                       attribute: NSLayoutAttributeWidth
                                                                       relatedBy: NSLayoutRelationEqual
                                                                          toItem: nil
                                                                       attribute: NSLayoutAttributeNotAnAttribute
                                                                      multiplier:1
                                                                        constant:200];
NSLayoutConstraint *heightConstraint = [NSLayoutConstraint constraintWithItem: customView
                                                                       attribute: NSLayoutAttributeHeight
                                                                       relatedBy: NSLayoutRelationEqual
                                                                          toItem: nil
                                                                       attribute: NSLayoutAttributeNotAnAttribute
                                                                      multiplier:1
                                                                        constant:200];

[customView addConstraints: @[widthConstraint, heightConstraint]];

NSLayoutConstraint *centerHorizontallyConstraint = [NSLayoutConstraint constraintWithItem: customView
                                                                                    attribute: NSLayoutAttributeCenterX
                                                                                    relatedBy: NSLayoutRelationEqual
                                                                                       toItem: self.view
                                                                                    attribute: NSLayoutAttributeCenterX
                                                                                   multiplier: 1
                                                                                     constant: 0];

NSLayoutConstraint *centerVerticallyConstraint = [NSLayoutConstraint constraintWithItem: customView
                                                                                    attribute: NSLayoutAttributeCenterY
                                                                                    relatedBy: NSLayoutRelationEqual
                                                                                       toItem: self.view
                                                                                    attribute: NSLayoutAttributeCenterY
                                                                                   multiplier: 1
                                                                                     constant: 0];

[self.view addConstraints: @[centerHorizontallyConstraint, centerVerticallyConstraint]];

Upvotes: 1

Related Questions