为什么UITableViewCell具有自动布局约束冲突

我有一个UITableViewSubclass(样式:UITableViewCellStyleValue1)具有自定义标签,实质上是正常的textLabel标签的替代品。 它应该与正常的textLabel左alignment,但有一个宽度可以在正常的detailTextLabel的左侧结束8个点。 我得到了期望的效果,但是当使用这些单元格时,会出现一个exception,无法同时满足约束条件。

我不明白的是为什么抱怨,没有明显的冲突。 在设置约束之后调用[self layoutIfNeeded]将使exception无效。 或者,降低configuration尾随属性的约束(例如, UILayoutPriorityDefaultHigh而不是默认的UILayoutPriorityRequired )的优先级也使该exceptionUILayoutPriorityRequired ,显然是因为我通知自动布局引擎可以打破/忽略该约束。

我假设标准的UITableView实现可能会奇怪地将textLabeltextLabel以一种使得它最初不可能描述所描述的视图的方式进行textLabel 。 例如,如果textLabel实际上放置在单元格的右侧,而detailTextLabel放置在左侧,那么我描述的布局将是不可能的。

自动布局何时生效,在这种情况下。 它是否跳起了枪,并试图在事情发生之前进行布局呢?

没有使用Storyboard或XIB。 纯粹的基于代码。

 #import "EBTStoreTableViewCell.h" @interface EBTStoreTableViewCell () @property (nonatomic, readonly, weak) UILabel *storeNameLabel; @end @implementation EBTStoreTableViewCell - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { self = [super initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:reuseIdentifier]; if (self) { self.textLabel.text = @" "; self.detailTextLabel.text = @" "; UILabel *storeNameLabel = [[UILabel alloc] init]; storeNameLabel.translatesAutoresizingMaskIntoConstraints = NO; [storeNameLabel setContentCompressionResistancePriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal]; [self.contentView addSubview:storeNameLabel]; _storeNameLabel = storeNameLabel; [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:storeNameLabel attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.textLabel attribute:NSLayoutAttributeLeading multiplier:1.0f constant:0.0f]]; [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:storeNameLabel attribute:NSLayoutAttributeBaseline relatedBy:NSLayoutRelationEqual toItem:self.textLabel attribute:NSLayoutAttributeBaseline multiplier:1.0f constant:0.0f]]; [self.contentView addConstraint:[NSLayoutConstraint constraintWithItem:storeNameLabel attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:self.detailTextLabel attribute:NSLayoutAttributeLeading multiplier:1.0f constant:-8.0f]]; // [self layoutIfNeeded]; // doing this makes the issue go away } return self; } // Setters ommited @end 

这是我得到的exception消息:

 2014-04-23 11:50:42.092 Application[32507:60b] Unable to simultaneously satisfy constraints. 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:0xde03910 UILabel:0xde036b0.leading == UILabel:0xde00590.leading>", "<NSLayoutConstraint:0xde03a30 UILabel:0xde036b0.trailing == UITableViewLabel:0xde00c10.leading - 8>", "<NSAutoresizingMaskLayoutConstraint:0xde01920 h=--& v=--& UILabel:0xde00590.midX ==>", "<NSAutoresizingMaskLayoutConstraint:0xde1de50 h=--& v=--& H:[UILabel:0xde00590(0)]>", "<NSAutoresizingMaskLayoutConstraint:0x17f50a10 h=--& v=--& UITableViewLabel:0xde00c10.midX ==>" ) Will attempt to recover by breaking constraint <NSLayoutConstraint:0xde03a30 UILabel:0xde036b0.trailing == UITableViewLabel:0xde00c10.leading - 8> Break on objc_exception_throw to catch this in the debugger. The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful. 

你不应该混合使用textLabeldetailTextLabel 。 这些不能被限制,因为他们的大小是内部pipe理,可能会产生意想不到的结果。

你应该创build自己的标签,然后对它们设置约束。

UITableViewCell的文档:

创build单元格时,可以自己定制它们或使用几种预定义样式之一。 预定义的单元格样式是最简单的选项。 使用预定义的样式,单元格提供位置和样式固定的标签和图像子视图。 您只需提供文本和图像内容即可进入这些固定视图。 要使用具有预定义样式的单元格,请使用initWithStyle:reuseIdentifier:方法对其进行初始化,或者在Xcode中使用该样式来configuration单元格。 要设置单元格的文本和图像,请使用textLabeldetailTextLabeldetailTextLabel属性。

如果您想超出预定义的样式,可以将子视图添加到单元格的contentView属性。 添加子视图时,您需要负责定位这些视图并自行设置其内容。