Search code examples
iosobjective-cios7ios8nslayoutconstraint

UIView breaking in iOS7 but not in iOS8


I have created a custom view to show 2 labels inside a circle. It is suppose to look like this: Looking correctly

but in iOS 7 it looks like this: Looking wrong

That happens because the constraints hat are supposed to stick the labels to the top/bottom are breaking for some reason, but only on iOS 7. I get the following error:

(
    "<NSLayoutConstraint:0x7f96e500a540 H:|-(-1)-[UILabel:0x7f96e2dd84d0]   (Names: '|':UIView:0x7f96e2df6350 )>" )

Will attempt to recover by breaking constraint  <NSLayoutConstraint:0x7f96e500a540 H:|-(-1)-[UILabel:0x7f96e2dd84d0]   (Names: '|':UIView:0x7f96e2df6350 )>

I have confirmed that those are in fact the constraints called (I only gave one error as an example)

self.dayLabelStickButtomConstraint
self.monthLabelStickTopConstraint

Here is the code for the custom view, can anyone maybe understand why is it breaking on iOS 7 but not on 8?

- (instancetype) initWithCoder:(NSCoder *)aDecoder {
    self = [super initWithCoder:aDecoder];
    if (self) {
        [self initiateValues];
        [self buildHeirarchy];
    }
    return self;
}

- (instancetype) initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    if (self) {
        [self initiateValues];
        [self buildHeirarchy];
    }
    return self;
}

-(void)initiateValues{
    self.fillColor = [UIColor blackColor];


    self.month = @"jan";
    self.monthFontSize = 8.0f;
    self.monthTextColor = [UIColor blackColor];
    self.monthLabelInsetDistance = 1.0f;

    self.day = @"01";
    self.dayFontSize = 12.0f;
    self.dayTextColor = [UIColor blackColor];
    self.dayLabelInsetDistance = 1.0f;
}

-(void)buildHeirarchy{
    self.innerContainer = [[UIView alloc] initWithFrame:CGRectInset(self.bounds, 5.0, 5.0)];
    [self.innerContainer setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self addSubview:self.innerContainer];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.innerContainer
                                                     attribute:NSLayoutAttributeCenterX
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeCenterX
                                                    multiplier:1.0
                                                      constant:0.0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.innerContainer
                                                     attribute:NSLayoutAttributeCenterY
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeCenterY
                                                    multiplier:1.0
                                                      constant:0.0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.innerContainer
                                                     attribute:NSLayoutAttributeWidth
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeWidth
                                                    multiplier:0.7
                                                      constant:0.0]];
    [self addConstraint:[NSLayoutConstraint constraintWithItem:self.innerContainer
                                                     attribute:NSLayoutAttributeHeight
                                                     relatedBy:NSLayoutRelationEqual
                                                        toItem:self
                                                     attribute:NSLayoutAttributeHeight
                                                    multiplier:0.7
                                                      constant:0.0]];


    self.monthLabel = [[UILabel alloc] initWithFrame:CGRectInset(self.bounds, 5.0, 5.0)];
    [self.monthLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
    self.monthLabel.textAlignment = NSTextAlignmentCenter;
    [self.innerContainer addSubview:self.monthLabel];

    [self.innerContainer addConstraint:[NSLayoutConstraint constraintWithItem:self.monthLabel
                                                                    attribute:NSLayoutAttributeCenterX
                                                                    relatedBy:NSLayoutRelationEqual
                                                                       toItem:self.innerContainer
                                                                    attribute:NSLayoutAttributeCenterX
                                                                   multiplier:1.0
                                                                     constant:0.0]];

    NSLayoutConstraint *monthTopConstraint = [NSLayoutConstraint constraintWithItem:self.monthLabel
                                                                          attribute:NSLayoutAttributeTopMargin
                                                                          relatedBy:NSLayoutRelationEqual
                                                                             toItem:self.innerContainer
                                                                          attribute:NSLayoutAttributeTopMargin
                                                                         multiplier:1.0
                                                                           constant:self.monthLabelInsetDistance];
    self.monthLabelStickTopConstraint = monthTopConstraint;
    [self.innerContainer addConstraint:self.monthLabelStickTopConstraint];


    self.dayLabel = [[UILabel alloc] initWithFrame:CGRectInset(self.bounds, 5.0, 5.0)];
    [self.dayLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
    [self.innerContainer addSubview:self.dayLabel];
    self.dayLabel.textAlignment = NSTextAlignmentCenter;

    [self.innerContainer addConstraint:[NSLayoutConstraint constraintWithItem:self.dayLabel
                                                                    attribute:NSLayoutAttributeCenterX
                                                                    relatedBy:NSLayoutRelationEqual
                                                                       toItem:self.innerContainer
                                                                    attribute:NSLayoutAttributeCenterX
                                                                   multiplier:1.0
                                                                     constant:0.0]];

    NSLayoutConstraint *dayButtomConstraint = [NSLayoutConstraint constraintWithItem:self.dayLabel
                                                                           attribute:NSLayoutAttributeBottomMargin
                                                                           relatedBy:NSLayoutRelationEqual
                                                                              toItem:self.innerContainer
                                                                           attribute:NSLayoutAttributeBottomMargin
                                                                          multiplier:1.0
                                                                            constant:self.dayLabelInsetDistance];

    self.dayLabelStickButtomConstraint = dayButtomConstraint;
    [self.innerContainer addConstraint:self.dayLabelStickButtomConstraint];



}

-(void)layoutSubviews{
    // get the graphics context
    if (!self.backgroundColorRoundView) {

        self.backgroundColorRoundView = [[UIView alloc]initWithFrame:self.bounds];
        [self addSubview:self.backgroundColorRoundView];
        [self sendSubviewToBack:self.backgroundColorRoundView];
        self.backgroundColorRoundLayer = [CAShapeLayer new];
        UIBezierPath *path = [UIBezierPath bezierPathWithOvalInRect:self.backgroundColorRoundView.bounds];
        self.backgroundColorRoundLayer.path = path.CGPath;
        //imageMaskLayer.fillColor = self.fillColor.CGColor;
        [self.backgroundColorRoundView.layer addSublayer:self.backgroundColorRoundLayer];
    }
    self.backgroundColorRoundView.frame = self.bounds;
    self.backgroundColorRoundLayer.frame = self.bounds;
    [self updateViews];
    [super layoutSubviews];

}

-(void)updateViews{
    self.monthLabel.textColor = self.monthTextColor;
    self.dayLabel.textColor = self.dayTextColor;
    self.backgroundColorRoundLayer.fillColor = self.fillColor.CGColor;
}

-(void)updateConstraints{
    self.dayLabelStickButtomConstraint.constant = self.dayLabelInsetDistance;
    self.monthLabelStickTopConstraint.constant = self.monthLabelInsetDistance;

    [super updateConstraints];

}

Solution

  • After a lot of messing around the answer lied in the restraints themselves. Once i switched from topMargin,bottomMargin to just top and bottom it worked