iOS以编程方式为表格视图单元格内容创buildNSLayoutConstraint

我想在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]; 

我应该怎么做?

几点意见:

  1. 您创build这个特定的约束是正确的。 显然,你不能只设置左边的约束,但是你需要指定明确定义单元格子视图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子类来简化跟踪您的自定义控件的过程,但我希望保持简单的例子。

  2. 如果您不确定是否已经明确定义了约束条件,请运行该应用程序,并在呈现用户界面后,暂停应用程序并在(lldb)提示符下input以下内容:

     po [[UIWindow keyWindow] _autolayoutTrace] 

    这会告诉你是否有任何的意见是不明确的定义(即是否有任何约束缺失)。

    如果要查看所有视图的frame ,可以在(lldb)提示符处input以下内容:

     po [[UIWindow keyWindow] recursiveDescription] 
  3. 确保为所有子视图指定translatesAutoresizingMaskIntoConstraintsNO ,就像我在上面的代码示例中所做的一样。

  4. 虽然可以使用constraintWithItem来定义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; }