自定义编程UITableViewCell的自动布局在滚动时失败

3
我正在尝试在通过程序实现的自定义UITableViewCell上使用iOS 6的新自动布局功能。我添加了addConstraint调用,并且一开始它能正常工作——直到我滚动。当我滚动后回来时,布局就被破坏了。被破坏的意思是字段之间的边距都不对了(太大了,超出了单元格的大小)。我猜测这可能与dequeueReusableCell方法有关,会让我得到一个“脏”的单元格,就像你发现自己需要重新初始化单元格内的字段一样,但我似乎无法做任何事情来使它再次正确地呈现。我尝试在返回单元格之前调用[self.contentView updateConstraints]。我尝试销毁约束并重新创建它们。不仅不起作用,而且如果在layoutSubviews中尝试它,它会陷入某种无限循环的冻结状态。有什么想法吗?
以下是建立约束的代码。它位于initWithStyle:reuseIdentifier:中:
[self.completedLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.nextSetHeaderLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.nextSetDetailLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.youWillLearnHeaderLabel setTranslatesAutoresizingMaskIntoConstraints:NO];
[self.youWillLearnDetailLabel setTranslatesAutoresizingMaskIntoConstraints:NO];

[self.contentView removeConstraints:[self.contentView constraints]];

NSDictionary *views = NSDictionaryOfVariableBindings(_completedLabel, _nextSetHeaderLabel, _nextSetDetailLabel, _youWillLearnHeaderLabel, _youWillLearnDetailLabel);

[self.contentView addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_completedLabel]-5-|"
                                         options:0
                                         metrics:nil
                                           views:views]];
[self.contentView addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_nextSetHeaderLabel]-5-|"
                                         options:0
                                         metrics:nil
                                           views:views]];

[self.contentView addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_nextSetDetailLabel]-5-|"
                                         options:0
                                         metrics:nil
                                           views:views]];

[self.contentView addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_youWillLearnHeaderLabel]-5-|"
                                         options:0
                                         metrics:nil
                                           views:views]];

[self.contentView addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"H:|-5-[_youWillLearnDetailLabel]-4-|"
                                         options:0
                                         metrics:nil
                                           views:views]];

[self.contentView addConstraints:
 [NSLayoutConstraint constraintsWithVisualFormat:@"V:|-5-[_completedLabel]-12-[_nextSetHeaderLabel]-0-[_nextSetDetailLabel]-12-[_youWillLearnHeaderLabel]-0-[_youWillLearnDetailLabel(>=20)]-1-|"
                                         options:0
                                         metrics:nil
                                           views:views]];
2个回答

1
我也遇到了这个问题。如果我不去划掉单元格,所有的东西都似乎能够正常工作 - 滚动、旋转等等。但是,如果我划掉单元格,那么布局就开始出现混乱。我能想到的唯一解决方法是重写单元格的prepareForReuse方法。在这个方法中,
    1. 删除所有自定义子视图
    2. 从contentView中删除与这些子视图相关的所有约束条件
    3. 再次添加子视图和约束条件
-(void) prepareForReuse
{
    [self removeCustomSubviewsFromContentView];
    [self.contentView removeConstraints:self.constraints] //self.constraits holds all the added constraints
    [self setupSubviewsInContentView];
    [self addConstraintsToContentView];
}

如果有更好的方法,我也很想学习:) 我相信dequeing的优点是tableView不必在内存中保存大量的单元格 - 但是,使用这种方法,每次出队都要花费几乎设置单元格的成本。

0

我遇到了类似的问题,如果有人感兴趣,我找到了一个解决方案,请看这个question

我所做的:

- (void)awakeFromNib
{
    [super awakeFromNib];

    for (NSLayoutConstraint *cellConstraint in self.constraints)
    {
        [self removeConstraint:cellConstraint];

        id firstItem = cellConstraint.firstItem == self ? self.contentView : cellConstraint.firstItem;
        id seccondItem = cellConstraint.secondItem == self ? self.contentView : cellConstraint.secondItem;

        NSLayoutConstraint* contentViewConstraint = [NSLayoutConstraint constraintWithItem:firstItem
                                                                                 attribute:cellConstraint.firstAttribute
                                                                                 relatedBy:cellConstraint.relation
                                                                                    toItem:seccondItem
                                                                                 attribute:cellConstraint.secondAttribute
                                                                                multiplier:cellConstraint.multiplier
                                                                                  constant:cellConstraint.constant];

        [self.contentView addConstraint:contentViewConstraint];
    }
}

2
麻烦的是原帖发布者正在寻求有关以编程方式创建UITableViewCell的提示,而您的是通过xib或storyboard创建的。这是完全不同的东西。 - Greg Combs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接