我想在cellForRowAtIndexPath中添加一些视图到我的单元格内容视图,对于它们的约束,但没有任何作用。我有这样的事情:
NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:imageView
attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:cell.contentView attribute:NSLayoutAttributeLeft multiplier:1.0f constant:10.0f];
[cell.contentView addConstraint:constraint];
我该怎么做?
答案 0 :(得分:49)
有几点意见:
您创建此特定约束是正确的。显然,您不能只设置左约束,但需要指定将明确定义单元格子视图的frame
的所有约束。例如,不仅要定义左(或前导)约束,还要定义顶部,底部和宽度约束。或者定义左约束加上宽度和高度约束,并指定垂直y约束。有很多不同的方法,但关键是你必须添加所有的约束,明确定义所有子视图的frame
。
例如,您可能会遇到以下内容:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
UIImageView *customImageView;
UILabel *customLabel;
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
customImageView = [[UIImageView alloc] init];
customImageView.translatesAutoresizingMaskIntoConstraints = NO;
customImageView.tag = IMAGEVIEWTAG;
[cell.contentView addSubview:customImageView];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeLeft
multiplier:1.0
constant:25.0]];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView
attribute:NSLayoutAttributeWidth
relatedBy:NSLayoutRelationEqual
toItem:nil
attribute:NSLayoutAttributeNotAnAttribute
multiplier:1.0
constant:30.0]];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:3.0]];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customImageView
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-3.0]];
customLabel = [[UILabel alloc] init];
customLabel.translatesAutoresizingMaskIntoConstraints = NO;
customLabel.tag = LABELTAG;
[cell.contentView addSubview:customLabel];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel
attribute:NSLayoutAttributeLeading
relatedBy:NSLayoutRelationEqual
toItem:customImageView
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:10.0]];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel
attribute:NSLayoutAttributeTrailing
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeTrailing
multiplier:1.0
constant:-10.0]];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel
attribute:NSLayoutAttributeTop
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeTop
multiplier:1.0
constant:3.0]];
[cell.contentView addConstraint:[NSLayoutConstraint constraintWithItem:customLabel
attribute:NSLayoutAttributeBottom
relatedBy:NSLayoutRelationEqual
toItem:cell.contentView
attribute:NSLayoutAttributeBottom
multiplier:1.0
constant:-3.0]];
}
else {
customImageView = (id)[cell.contentView viewWithTag:IMAGEVIEWTAG];
customLabel = (id)[cell.contentView viewWithTag:LABELTAG];
}
customImageView.image = ...;
customLabel.text = ...;
return cell;
}
显然,您经常使用UITableViewCell
子类来促进跟踪自定义控件的过程,但我希望保持示例简单。
如果您不确定是否已明确定义约束,请运行应用程序,并在呈现UI后,暂停应用程序并在(lldb)
提示符下输入以下内容:
po [[UIWindow keyWindow] _autolayoutTrace]
如果任何视图被明确定义(即是否缺少任何约束),这将通知您。
如果您想查看frame
对所有观看的内容,可以在(lldb)
提示符下输入以下内容:
po [[UIWindow keyWindow] recursiveDescription]
请务必为所有子视图指定translatesAutoresizingMaskIntoConstraints
到NO
,就像我在上面的代码示例中所做的那样。
虽然您可以使用constraintWithItem
定义约束,但人们通常会使用constraintsWithVisualFormat
,因为您通常可以更简洁地定义约束。将上面的代码示例与此代码示例进行对比:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *cellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
UIImageView *customImageView;
UILabel *customLabel;
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
customImageView = [[UIImageView alloc] init];
customImageView.translatesAutoresizingMaskIntoConstraints = NO;
customImageView.tag = IMAGEVIEWTAG;
[cell.contentView addSubview:customImageView];
customLabel = [[UILabel alloc] init];
customLabel.translatesAutoresizingMaskIntoConstraints = NO;
customLabel.tag = LABELTAG;
[cell.contentView addSubview:customLabel];
NSDictionary *views = NSDictionaryOfVariableBindings(customImageView, customLabel);
[cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-25-[customImageView(30)]-[customLabel]|" options:0 metrics:nil views:views]];
[cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-3-[customImageView]-3-|" options:0 metrics:nil views:views]];
[cell.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-3-[customLabel]-3-|" options:0 metrics:nil views:views]];
}
else {
customImageView = (id)[cell.contentView viewWithTag:IMAGEVIEWTAG];
customLabel = (id)[cell.contentView viewWithTag:LABELTAG];
}
customImageView.image = ...;
customLabel.text = ...;
return cell;
}