UITableViewCell 的 NSLayoutConstraint:约束必须包含第一个布局项
Posted
技术标签:
【中文标题】UITableViewCell 的 NSLayoutConstraint:约束必须包含第一个布局项【英文标题】:NSLayoutConstraint for UITableViewCell: Constraint must contain a first layout item 【发布时间】:2017-12-13 14:45:13 【问题描述】:我正在尝试在我的每个自定义单元格(继承自 UITableViewCell
)中设置 NSLayoutConstraint
,而不是在 UIViewController
中指定它们,以避免通过公开每种单元格类型的约束来使其混乱。
问题是我找不到单元格生命周期的适当部分来创建布局约束(我尝试了layoutSubviews()
和awakeFromNib()
),但是它们都在单元格的生命周期中被调用得太早,当它的@ 987654327@ 尚未定义 - 它会导致此错误:
约束必须包含第一个布局项
既然UITableViewCell
没有viewDidLoad()
像UIViewController
这样的方法,那么如何定义单元格内的布局约束?
layoutSubviews()
的自定义UITableViewCell
:
- (void) layoutSubviews
self.translatesAutoresizingMaskIntoConstraints = false;
[[NSLayoutConstraint constraintWithItem: self.attributeNameLabel
attribute: NSLayoutAttributeLeading
relatedBy: NSLayoutRelationEqual
toItem: self.contentView
attribute: NSLayoutAttributeLeading
multiplier: 1
constant: 3] setActive:true];
[[NSLayoutConstraint constraintWithItem: self.attributeNameLabel
attribute: NSLayoutAttributeTop
relatedBy: NSLayoutRelationEqual
toItem: self.contentView
attribute: NSLayoutAttributeTop
multiplier: 1
constant: 3] setActive:true];
[[NSLayoutConstraint constraintWithItem: self.attributeNameLabel
attribute: NSLayoutAttributeRight
relatedBy: NSLayoutRelationEqual
toItem: self.contentView
attribute: NSLayoutAttributeRight
multiplier: 1
constant: 3] setActive:true];
[[NSLayoutConstraint constraintWithItem: self.attributeNameLabel
attribute: NSLayoutAttributeBottom
relatedBy: NSLayoutRelationEqual
toItem: self.contentView
attribute: NSLayoutAttributeBottom
multiplier: 1
constant: 3] setActive:true];
UIViewController
中的示例初始化:
- (UITableViewCell *)tableView:(UITableView *)view cellForRowAtIndexPath:(NSIndexPath *)indexPath
UITableViewCell *cell;
if (indexPath.row % 2 == 0)
cell = [[CustomCell1 alloc] init];
else if (indexPath.row % 2 == 1)
cell = [[CustomCell2 alloc] init];
else if (...)
...
return cell;
【问题讨论】:
你没有使用xib或storyboard? 我不想使用故事板,因为我有许多不同的单元格类型(具有继承等)......它很快就会变得混乱 你有没有在设置约束后尝试过updateConstraintsIfNeeded()? 不,我不能,应用程序甚至没有设置第一个约束。它在这一行崩溃:[[NSLayoutConstraint constraintWithItem:...
尝试使用锚点。它更清洁。见here
【参考方案1】:
尝试制作
self.attributeNameLabel.translatesAutoresizingMaskIntoConstraints = NO;
对于每个标签而不是 contentView
将它们转换成对我有用的方式
这样做
- (void)awakeFromNib
// Initialization code
[super awakeFromNib];
UILabel*ddd = [UILabel new];
ddd.text = @"adsbcujklasdcbaksci";
ddd.translatesAutoresizingMaskIntoConstraints = NO ;
[self.contentView addSubview:ddd];
NSLayoutConstraint*ss1 = [NSLayoutConstraint constraintWithItem: ddd
attribute: NSLayoutAttributeCenterX
relatedBy: NSLayoutRelationEqual
toItem: self.contentView
attribute: NSLayoutAttributeCenterX
multiplier: 1 constant: 3] ;
NSLayoutConstraint*ss2 = [NSLayoutConstraint constraintWithItem: ddd
attribute: NSLayoutAttributeCenterY
relatedBy: NSLayoutRelationEqual
toItem: self.contentView
attribute: NSLayoutAttributeCenterY
multiplier: 1 constant: 3] ;
[self.contentView addConstraints:@[ss1,ss2]];
[self layoutSubviews];
[self layoutIfNeeded];
【讨论】:
在这种情况下需要哪些元素?在此示例中,我仅访问self.contentView
和 self.attributeNameLabel
,但仍然收到有关缺少第一个布局项的错误。
在你的函数末尾添加上面两行
仅此一项不起作用,同样的错误。顺便说一句,我打电话给layoutSubviews()
没有问题。它会自动调用,而不会将其添加到函数的末尾。
这行得通,在接受答案之前我必须仔细查看它。以上是关于UITableViewCell 的 NSLayoutConstraint:约束必须包含第一个布局项的主要内容,如果未能解决你的问题,请参考以下文章
UIScrollView 右侧的 Autolayout Pin 视图