3

我正在尝试将自定义UITableViewCell类中的子视图固定到单元格的左侧contentView。我将子视图添加到子类contentView的方法内部,initWithStyle并在该方法内部添加约束。不幸的是,我有两个问题:

  1. contentView即使我使用以下代码执行此操作,子视图也没有固定到左侧边缘:

    [self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_animatedView]-[_aTextField][_rightImageView]|"
                                                                             options:NSLayoutFormatDirectionLeftToRight
                                                                             metrics:nil views:viewDictionary]];
    

    对我来说,该格式字符串应该将 固定_animatedView到 的左侧contentView,然后将其他后续视图附加到尽可能靠近的位置。相反,所有三个视图都以正确的顺序一起显示在 中间contentView,而不是在左边缘。我是使用自动布局的新手,所以这可能是我对格式字符串如何工作的困惑。

  2. 已解决:感谢 Guillaume 的建议,我能够进行一些测试,发现当我滚动表格时单元格内容大量移位的原因是我没有覆盖该UITableViewCell方法,prepareForReuse. UITableViewCell当准备重用a 以显示 中另一个对象的信息时调用此方法UITableView,这在发生滚动时偶然发生。解决方案就像将以下代码插入我的UITableViewCell子类一样简单:

    -(void) prepareForReuse
     {
         [self setNeedsUpdateConstraints];
     }
    

另一个问题是,在我选择使用自定义单元格的 TableView 行之前,似乎没有强制执行约束。initWithStyle除了我应该设置约束之外,还有其他地方吗?或者这是一个不同的问题?

更新:

自定义表格单元.m

@interface ListTableCell ()
{
    NSDictionary *_viewsForConstraints;    // Used inside updateConstraints method.
    NSArray *_animatedViewSizeConstraints;
    NSArray *_centeringConstraints;
    NSArray *_horizontalConstraints;
}
@end

 - (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self)
    {
       // Set up the cell elements.
       self.contentView.translatesAutoresizingMaskIntoConstraints = NO;

       self.animatedView = [[AnimatedView alloc] initWithFrame:CGRectZero];
       self.animatedView.translatesAutoresizingMaskIntoConstraints = NO;
       [self.contentView addSubview:self.animatedView];

       self.aTextField = [[UITextField alloc] initWithFrame:CGRectZero];
       self.aTextField.textColor = [UIColor whiteColor];
       self.aTextField.translatesAutoresizingMaskIntoConstraints = NO;
       [self.contentView addSubview:self.aTextField];

       self.rightImageView = [[UIImageView alloc] initWithFrame:CGRectZero];
       self.rightImageView.translatesAutoresizingMaskIntoConstraints = NO;
       [self.contentView addSubview:self.rightImageView];

       _viewForConstraints = NSDictionaryOfVariableBindings(_animatedView,   
       _aTextField, _rightImageView);

       // Add height/width constraints to the animated view.
       NSLayoutConstraint *heightConstraint =
       [NSLayoutConstraint constraintWithItem:self.animatedView attribute:NSLayoutAttributeHeight relatedBy:0 toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1  constant:self.contentView.frame.size.height];
       NSLayoutConstraint *aspectRatioConstraint = [NSLayoutConstraint constraintWithItem:self.animatedView attribute:NSLayoutAttributeHeight relatedBy:0 toItem:self.animatedview attribute:NSLayoutAttributeWidth multiplier:1.0 constant:0];

       _animatedViewSizeConstraints = @[heightConstraint, aspectRatioConstraint];

       // Center elements vertically.

       NSLayoutConstraint *animatedViewVerticalCenterConstraint =
       [NSLayoutConstraint constraintWithItem:self.animatedView
                                 attribute:NSLayoutAttributeCenterY
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.contentView
                                 attribute:NSLayoutAttributeCenterY
                                multiplier:1.0
                                  constant:0.0];
        NSLayoutConstraint *aTextFieldVerticalCenterConstraint =
        [NSLayoutConstraint constraintWithItem:self.aTextField
                                 attribute:NSLayoutAttributeCenterY
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.contentView
                                 attribute:NSLayoutAttributeCenterY
                                multiplier:1.0
                                  constant:0.0];
        NSLayoutConstraint *rightImageVerticalCenterConstraint =
        [NSLayoutConstraint constraintWithItem:self.rightImageView
                                 attribute:NSLayoutAttributeCenterY
                                 relatedBy:NSLayoutRelationEqual
                                    toItem:self.contentView
                                 attribute:NSLayoutAttributeCenterY
                                multiplier:1.0
                                  constant:0.0];

       _centeringConstraints = @[animatedViewVerticalCenterConstraint,
                                 aTextFieldVerticalCenterConstraint, rightImageVerticalCenterConstraint];

       _horizontalConstraints = [NSLayoutConstraint constraintsWithVisualFormat:@"|[_animatedView]-[_aTextField][_rightImageView]|"
                options:NSLayoutFormatDirectionLeftToRight metrics:nil views:viewDictionary]];
       self.backgroundColor = [UIColor greenColor];
       self.editingAccessoryType = UITableViewCellAccessoryNone;
       self.accessoryType = UITableViewCellAccessoryNone;
       self.selectionStyle = UITableViewCellSelectionStyleNone;
       self.aTextField.userInteractionEnabled = NO;

       [self setNeedsUpdateConstraints];
  }

-(void) updateConstraints
{
    [super updateConstraints];

    [self.contentView addConstraints:_animatedViewSizeConstraints];
    [self.contentView addConstraints:_centeringConstraints];
    [self.contentView addConstraints:_horizontalConstraints];
}

表视图控制器.m

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
 {
    static NSString *CellIdentifier = @"Cell";
    CustomTableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];

    // Configure the cell.
    cell.aTextField.text = @"Test Text";
    cell.aTextField.delegate = self;

    return cell;
}

我可以确认它initWithStyle被调用了,因为背景总是绿色并且子视图总是出现,它们最初只是显示得很奇怪。

感谢您对此的任何帮助!

4

2 回答 2

2

您应该在updateConstraints方法中设置约束。从文档:

自己设置约束的自定义视图应该通过覆盖此方法来实现。

至少应该解决您的#2问题。

于 2013-06-15T20:52:25.263 回答
0

不要关闭你translatesAutoresizingMaskIntoConstraintscontentView表格视图。

我以前遇到过这个问题。

删除这一行:self.contentView.translatesAutoresizingMaskIntoConstraints = NO;

本质上,您的视图固定在左侧边缘,contentView但内容视图不是单元格的整个宽度。您可以使用类似DCIntrospect-ARC或 Reveal 之类的东西来查看情况。

于 2014-08-26T18:32:06.907 回答