I'm updating my app for iOS8 and noticed a change of behavier with [NSLayoutConstraint constraintWithItem: ..].
This works fine in iOS7, but in iOS8 having a constraint with a view that is a nested subview is not working correctly.
NSLayoutConstraint *myConstraint = [NSLayoutConstraint constraintWithItem:myView.mySubview.label attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:label2 attribute:NSLayoutAttributeBottom multiplier:1.0 constant:10.0];
Essentially, it looks like because myView.mySubview.label y coordinates are 0 within it's immediate superview (mySubview), it places label2 with respect to y=0. However the top most parent view (myView) has an arbitrary y coordinate that the constraint is not respecting. It's as if Autolayout is just taking the y coordinate of the view within its immediate superview and not in context of everything. Again this same line works fine in iOS7.
If I apply the constraint to just top level views:
NSLayoutConstraint *myConstraint = [NSLayoutConstraint constraintWithItem:label1 attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:label2 attribute:NSLayoutAttributeBottommultiplier:1.0 constant:10.0];
This works fine on iOS7 and 8.
New behavior or iOS8 bug?
Seems like an iOS8 bug... it's affecting my project as well. Reproducible with the following bit of code, where I can see notWorkingLabel in iOS7 but not iOS8:
#import "ViewController.h"
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIView *container = [UIView new];
container.translatesAutoresizingMaskIntoConstraints = NO;
[self.view addSubview:container];
UILabel *workingLabel = [UILabel new];
workingLabel.backgroundColor = [UIColor lightGrayColor];
workingLabel.translatesAutoresizingMaskIntoConstraints = NO;
workingLabel.text = @"This is a visible label";
workingLabel.font = [UIFont systemFontOfSize:20];
[container addSubview:workingLabel];
UIView *subContainer = [UILabel new];
subContainer.backgroundColor = [UIColor yellowColor];
subContainer.translatesAutoresizingMaskIntoConstraints = NO;
[container addSubview:subContainer];
UILabel *notWorkingLabel = [UILabel new];
notWorkingLabel.backgroundColor = [UIColor lightGrayColor];
notWorkingLabel.translatesAutoresizingMaskIntoConstraints = NO;
notWorkingLabel.text = @"This label is not visible";
notWorkingLabel.font = [UIFont systemFontOfSize:20];
[subContainer addSubview:notWorkingLabel];
NSDictionary *views = NSDictionaryOfVariableBindings(container, workingLabel, subContainer, notWorkingLabel);
[subContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[notWorkingLabel]-|" options:0 metrics:nil views:views]];
[subContainer addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-[notWorkingLabel]-|" options:0 metrics:nil views:views]];
[container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[workingLabel]|" options:0 metrics:nil views:views]];
[container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[subContainer]|" options:0 metrics:nil views:views]];
[container addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-50-[workingLabel]-20-[subContainer]" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[container]|" options:0 metrics:nil views:views]];
[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[container]|" options:0 metrics:nil views:views]];
}
@end
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With