我正在尝试将自定义UITableViewCell
类中的子视图固定到单元格的左侧contentView
。我将子视图添加到子类contentView
的方法内部,initWithStyle
并在该方法内部添加约束。不幸的是,我有两个问题:
contentView
即使我使用以下代码执行此操作,子视图也没有固定到左侧边缘:[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_animatedView]-[_aTextField][_rightImageView]|" options:NSLayoutFormatDirectionLeftToRight metrics:nil views:viewDictionary]];
对我来说,该格式字符串应该将 固定
_animatedView
到 的左侧contentView
,然后将其他后续视图附加到尽可能靠近的位置。相反,所有三个视图都以正确的顺序一起显示在 中间contentView
,而不是在左边缘。我是使用自动布局的新手,所以这可能是我对格式字符串如何工作的困惑。已解决:感谢 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
被调用了,因为背景总是绿色并且子视图总是出现,它们最初只是显示得很奇怪。
感谢您对此的任何帮助!