0

我有一个 UITableViewController,分组样式,带有一个自定义 UITableViewCell。在 UITableViewCell 中,我有 NSLayoutConstraints,在故事板(原型单元格上)中定义,它决定了 UIImageView 的大小和位置。这些 NSLayoutConstraints 链接到 UITableViewCell 子类的属性。

在子类 UITableViewCell 的 -(void)layoutSubviews 方法中,我正在尝试使用

self.topSpacingConstraint.constant = 0;

在每个单元格的基础上更改排列。

不过,那行代码调整了我所有单元格的约束。我不明白为什么,也不知道如何为单个单元格设置约束。

更新

-(void)layoutSubviews这是 UITableViewCell 子类的方法的完整代码。self.topCell并且self.bottomCell是在配置单元格时由 UITableViewController 设置的属性。基于这些值,我试图在每个单元格的基础上更新图像的 AutoLayout 间距:

- (void)layoutSubviews
{
    [super layoutSubviews];

    UIImage *mask;

    if (self.topCell && self.bottomCell) {
        self.imageSpacingTopConstraint.constant = 1;
        self.imageSpacingBottomConstraint.constant = 2;
        mask = MTDContextCreateRoundedMask(self.wineImage.bounds, 6.0, 0.0, 6.0, 0.0);
    } else if (self.topCell) {
        self.imageSpacingTopConstraint.constant = 1;
        self.imageSpacingBottomConstraint.constant = 0;
        mask = MTDContextCreateRoundedMask(self.wineImage.bounds, 6.0, 0.0, 0.0, 0.0);
    } else if (self.bottomCell) {
        self.imageSpacingTopConstraint.constant = 0;
        self.imageSpacingBottomConstraint.constant = 2;
        mask = MTDContextCreateRoundedMask(self.wineImage.bounds, 0.0, 0.0, 6.0, 0.0);
    } else {
        self.imageSpacingTopConstraint.constant = 0;
        self.imageSpacingBottomConstraint.constant = 0;
        mask = MTDContextCreateRoundedMask(self.wineImage.bounds, 0.0, 0.0, 0.0, 0.0);
    }

    CALayer *layerMask = [CALayer layer];
    layerMask.frame = self.wineImage.bounds;
    layerMask.contents = (id)mask.CGImage;
    self.wineImage.layer.mask = layerMask;
}

我需要这样做是因为表格上分组样式的单元格高度不一致。顶部和底部单元格比“中间”单元格高 1pt,而表格中的单个单元格高 2pts。对所有单元格中的图像使用相同的间距约束会导致图像部分遮挡某些单元格的单元格边界,或者在图像和其他单元格的边界之间留下空白。

如果有人能想出一种更简单的方法来攻击它,我将不胜感激。

解决方案

根据下面标记的解决方案,删除图像间距约束,然后在图像和 cell.contentView 之间创建新的约束就可以了。我删除了代码以调整-(void)layoutSubviews方法中的约束。我添加了代码以删除awakeFromNibUITableViewCell 子类并对其进行新约束:

- (void)awakeFromNib
{
    [super awakeFromNib];

    // Since Xcode 4.6.3 creates constrain relationships between the image and the cell, we need to delete and then recreate between the image and the cell.contentView

    [self removeConstraint:self.imageSpacingTopConstraint];
    [self removeConstraint:self.imageSpacingBottomConstraint];

    self.imageSpacingTopConstraint = [NSLayoutConstraint constraintWithItem:self.wineImage attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0];
    self.imageSpacingBottomConstraint = [NSLayoutConstraint constraintWithItem:self.wineImage attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.contentView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0];

    [self addConstraint:self.imageSpacingTopConstraint];
    [self addConstraint:self.imageSpacingBottomConstraint];
}
4

2 回答 2

2

一个问题是您正在更新您的约束layoutSubviews,但在自动布局之后layoutSubviews运行 。您应该改为更新您的约束。updateConstraints

另一个问题是 Xcode,至少到 4.6.3 版本,是错误的。您的图像视图是单元格的子视图contentView,并且约束应该在图像视图和contentView. 但是在笔尖和故事板中,Xcode错误地设置了图像视图和单元格之间的约束。(注意:这个问题在 Xcode 5 中已经修复,所以如果你正在阅读这篇文章,除非你是一个时间旅行者,否则你可能不需要担心它。)

如果您在调试器中查看视图层次结构,您会发现单元格具有不同的高度,但它们的内容视图都具有相同的高度。以下是默认尺寸:

Section Size  Row Position  Cell Height   contentView Height

     1            sole          46              43

     2            first         45              43
     2           second         45              43

     3+           first         45              43
     3+          middle         44              43
     3+           last          45              43

因此,当您依赖 nib/storyboard 中的约束来定位单元格的子视图时,您最终会遇到问题。

最简单的解决方案是只编写代码(在您的单元格中awakeFromNib)从笔尖/故事板中删除约束,contentView并在图像视图和图像视图(以及 的任何其他子视图contentView)之间创建新的约束。这应该消除修改基于单元格在其部分中的位置的约束常数。

于 2013-06-30T20:27:52.620 回答
0

您的代码中没有条件。因此,所有单元格都发生了变化。

现在您已经添加了代码,想到了两个可能的原因:

  1. 如果 topCell 不是 ,则 if 语句将永远不会产生 0 常量nil。这似乎不完全合乎逻辑。

  2. if 语句下方的层部分可能会再次更改预期的布局。

于 2013-06-30T07:52:44.493 回答