【发布时间】:2015-03-07 16:03:23
【问题描述】:
我开始以编程方式使用自动布局和约束,但我不明白为什么会收到以下警告
Probably at least one of the constraints in the following list is one you don't want. Try this: (1) look at each constraint and try to figure out which you don't expect; (2) find the code that added the unwanted constraint or constraints and fix it. (Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints)
(
"<NSLayoutConstraint:0x7fbbd142ead0 'UIView-Encapsulated-Layout-Height' V:[UITableViewCellContentView:0x7fbbd162ec70(44)]>",
"<NSLayoutConstraint:0x7fbbd1431740 V:|-(20)-[UILabel:0x7fbbd174e520'Liked'] (Names: '|':UITableViewCellContentView:0x7fbbd162ec70 )>",
"<NSLayoutConstraint:0x7fbbd1431790 V:[UILabel:0x7fbbd174e520'Liked']-(NSSpace(8))-[UILabel:0x7fbbd174e7e0's']>",
"<NSLayoutConstraint:0x7fbbd14317e0 V:[UILabel:0x7fbbd174e7e0's']-(20)-| (Names: '|':UITableViewCellContentView:0x7fbbd162ec70 )>"
)
我知道导致错误的代码行是:
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[nameLbl]-[notificationLbl]-[textLabel]-20-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:views];
但我不明白为什么不能满足约束。这可能是一个愚蠢的问题,但我是自动布局的新手,而且由于文档不完整,这个话题令人困惑。我尝试了不同的变体和解决方案,但未能找到正确的。我错过了什么?我还粘贴了我的自定义表格视图单元格的代码以进行更详细的检查。
@implementation NotificationCell
@synthesize nameLbl,notificationLbl,textLabel,timeLbl,profileImgView,notificationImgView,clockImgView,didSetupConstraints;
-(id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
nameLbl = [[UILabel alloc]init];
[nameLbl setTextColor:[UIColor blueColor]];
nameLbl.translatesAutoresizingMaskIntoConstraints = NO;
[nameLbl setTextAlignment:NSTextAlignmentLeft];
[nameLbl setNumberOfLines:1];
[nameLbl setBackgroundColor:[UIColor redColor]];
[self.contentView addSubview:nameLbl];
notificationLbl = [[UILabel alloc]init];
[notificationLbl setTextColor:[UIColor lightGrayColor]];
notificationLbl.translatesAutoresizingMaskIntoConstraints = NO;
[notificationLbl setTextAlignment:NSTextAlignmentLeft];
[notificationLbl setNumberOfLines:1];
[self.contentView addSubview:notificationLbl];
textLabel = [[UILabel alloc]init];
[textLabel setTextColor:[UIColor blueColor]];
textLabel.translatesAutoresizingMaskIntoConstraints = NO;
[textLabel setTextAlignment:NSTextAlignmentLeft];
[textLabel setNumberOfLines:0];
[textLabel setBackgroundColor:[UIColor grayColor]];
[self.contentView addSubview:textLabel];
timeLbl = [[UILabel alloc]init];
[timeLbl setTextColor:[UIColor grayColor]];
timeLbl.translatesAutoresizingMaskIntoConstraints = NO;
[timeLbl setTextAlignment:NSTextAlignmentLeft];
[timeLbl setNumberOfLines:1];
[self.contentView addSubview:timeLbl];
profileImgView = [[UIImageView alloc]init];
[profileImgView setTranslatesAutoresizingMaskIntoConstraints:NO];
[profileImgView setBackgroundColor:[UIColor redColor]];
[profileImgView.layer setCornerRadius:20];
[profileImgView.layer setMasksToBounds:YES];
[self.contentView addSubview:profileImgView];
clockImgView = [[UIImageView alloc]init];
[clockImgView setTranslatesAutoresizingMaskIntoConstraints:NO];
[clockImgView setBackgroundColor:[UIColor blueColor]];
[clockImgView.layer setCornerRadius:10];
[clockImgView.layer setMasksToBounds:YES];
[self.contentView addSubview:clockImgView];
notificationImgView = [[UIImageView alloc]init];
[notificationImgView setTranslatesAutoresizingMaskIntoConstraints:NO];
[notificationImgView setBackgroundColor:[UIColor purpleColor]];
[notificationImgView.layer setCornerRadius:10];
[notificationImgView.layer setMasksToBounds:YES];
[self.contentView addSubview:notificationImgView];
/*[self.view addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[_headerView(==80)]-0-[_tableView]-|"
options:NSLayoutFormatDirectionLeadingToTrailing
metrics:nil
views:elementsDict]];*/
}
return self;
}
-(void)updateConstraints{
if (self.didSetupConstraints == NO) {
NSDictionary *views = NSDictionaryOfVariableBindings(nameLbl,notificationLbl,notificationImgView,textLabel,timeLbl,profileImgView,clockImgView);
NSArray *constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-[profileImgView(40)]-10-[textLabel]-[clockImgView(20)]-[timeLbl(20)]-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:views];
[self.contentView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[profileImgView]-10-[nameLbl]-[clockImgView]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:views];
[self.contentView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"H:[profileImgView]-10-[notificationImgView(20)]-[notificationLbl]-[clockImgView]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:views];
[self.contentView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-20-[nameLbl]-[notificationLbl]-[textLabel]-20-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:views];
[self.contentView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:[notificationImgView(20)]-[textLabel]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:views];
[self.contentView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-15-[profileImgView(40)]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:views];
[self.contentView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-15-[clockImgView(20)]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:views];
[self.contentView addConstraints:constraints];
constraints = [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-15-[timeLbl]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:views];
[self.contentView addConstraints:constraints];
self.didSetupConstraints = YES;
}
[super updateConstraints];
}
- (void)layoutSubviews
{
[super layoutSubviews];
[self.contentView setNeedsLayout];
[self.contentView layoutIfNeeded];
self.textLabel.preferredMaxLayoutWidth = CGRectGetWidth(self.textLabel.frame);
}
【问题讨论】:
-
您需要支持哪些iOS版本? (此行为在 iOS 8 中有所改变。)当您收到上述警告时,您运行的是哪个 iOS 版本?另外,我假设您没有使用单元原型,而是有一个
cellForRowAtIndexPath手动实例化它?也许分享单元格的创建方式,因为行为因单元格的创建方式而异。 -
我有一个原型单元,但我正在以编程方式创建它,正如您从上面的代码中看到的那样,您的观点是什么?我正在 iOS 8 上进行测试。
-
如果你使用单元原型,它会用
initWithCoder实例化单元,而不是initWithStyle,这就是我问这个问题的原因。我只询问原型是因为(尤其是 iOS 7),行为很大程度上取决于您如何创建单元格,而您没有与我们分享。在一个单独的主题上,我很惊讶您在添加子视图后没有调用setNeedsUpdateConstraints(这是一个通常调用的方法,以便操作系统为您调用updateConstraints;但是无论如何该方法是如何被调用的)。 -
其实我在
cellForRowAtIndexPath方法中调用setNeedsUpdateConstraints。
标签: ios autolayout nslayoutconstraint visual-format-language