我正在尝试将自定义UITableViewCell
类内的子视图固定到单元格contentView
的左侧。我正在将子视图添加到子类的contentView
方法内的initWithStyle
内,并在该方法中添加约束。不幸的是,我有两个问题:
子视图未固定到contentView
的左边缘,即使我使用以下代码执行此操作:
[self.contentView addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"|[_animatedView]-[_aTextField][_rightImageView]|"
options:NSLayoutFormatDirectionLeftToRight
metrics:nil views:viewDictionary]];
对我来说,该格式字符串应该将_animatedView
固定到contentView
的左侧,然后将其他后续视图添加到尽可能接近的后面。相反,所有三个视图在contentView
的中间以正确的顺序显示在一起,而不是在左边缘。我是新手使用autolayout,所以这可能会混淆我的格式字符串是如何工作的。
解决:感谢Guillaume的建议,我能够进行一些测试,并发现当我滚动表格时单元格内容被大幅移位的原因是我没有覆盖UITableViewCell
方法,prepareForReuse
。当UITableViewCell
准备重用以显示UITableView
中另一个对象的信息时会调用此方法,这在滚动发生时偶然发生。解决方案就像将以下代码插入到我的UITableViewCell
子类中一样简单:
-(void) prepareForReuse
{
[self setNeedsUpdateConstraints];
}
另一个问题是,在我选择使用自定义单元格的TableView行之前,约束似乎不会被强制执行。是否有initWithStyle
以外的其他地方我应该设置约束,还是这是一个不同的问题?
更新
CustomTableCell.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];
}
TableViewController.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
被调用了,因为背景总是绿色,子视图总是显示出来,它们最初只显示奇怪的间距。
感谢您对此有任何帮助!
答案 0 :(得分:2)
答案 1 :(得分:0)
请勿关闭工作台视图translatesAutoresizingMaskIntoConstraints
的{{1}}。
我之前遇到过这个问题。
删除此行:contentView
基本上,您的视图 固定在self.contentView.translatesAutoresizingMaskIntoConstraints = NO;
的左边缘,但内容视图不是单元格的整个宽度。您可以使用contentView
或Reveal之类的内容来查看情况。