关于单元重用的自定义 UITableViewCell 约束问题
Posted
技术标签:
【中文标题】关于单元重用的自定义 UITableViewCell 约束问题【英文标题】:Custom UITableViewCell constraint issue on cell reuse 【发布时间】:2016-01-27 04:37:20 【问题描述】:我有一个自定义的UITableViewCell
,它具有动态图像高度。创建单元格时,所有调整大小的工作都按预期进行。问题是一旦单元格被UITableView
重用,图像高度的约束就会改变,并导致“无法同时满足约束”错误。
我尝试在重置之前停用高度限制,但它仍然会导致错误。
关于设置高度锚。这每次都会创建一个新实例,是否从内存中释放了停用的约束?有没有办法以这种格式更新当前约束?
我应该在 - (void)prepareForReuse 方法中做些什么吗?
感谢您的帮助
// Within Custom UITableViewCell
// The cell is a prototype cell in StoryBoard
// The width of the image is fixed and already set
// Observe when the image is set for imgView
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSString *,id> *)change context:(void *)context
if ([keyPath isEqualToString:@"image"])
if(self.imgView.image)
CGFloat ratio = self.imgView.image.size.height / self.imgView.image.size.width;
self.imageHeightConstraint.active = NO;
self.imageHeightConstraint = [self.imgView.heightAnchor constraintEqualToAnchor:self.imgView.widthAnchor multiplier:ratio];
self.imageHeightConstraint.identifier = @"imageHeightConstraint";
self.imageHeightConstraint.active = YES;
UITableViewCell
自动调整大小,因为 UIImageView
在 UIStackView
中,其顶部和底部锚点固定在单元格 contentView
的顶部和底部。
- (void)buildUI
UIStackView *containerStackView = [UIStackView new];
[self.contentView addSubview:containerStackView];
containerStackView.translatesAutoresizingMaskIntoConstraints = NO;
containerStackView.axis = UILayoutConstraintAxisHorizontal;
containerStackView.distribution = UIStackViewDistributionFill;
containerStackView.alignment = UIStackViewAlignmentCenter;
containerStackView.spacing = 10;
[containerStackView.topAnchor constraintEqualToAnchor:self.contentView.topAnchor constant:10.0].active = YES;
[containerStackView.centerXAnchor constraintEqualToAnchor:self.contentView.centerXAnchor].active = YES;
[containerStackView.widthAnchor constraintEqualToAnchor:self.contentView.widthAnchor multiplier:kImageWidthMultiplier].active = YES;
[containerStackView.bottomAnchor constraintEqualToAnchor:self.contentView.bottomAnchor constant:-30.0].active = YES;
self.imgView = [UIImageView new];
[containerStackView addArrangedSubview:self.imgView];
self.imgView.translatesAutoresizingMaskIntoConstraints = NO;
[self.imgView.widthAnchor constraintEqualToAnchor:containerStackView.widthAnchor multiplier:0.492].active = YES;
【问题讨论】:
当你改变imageView的高度时,你是否也在增加UITableViewCell的高度?self.imageHeightConstraint
是 weak
还是 strong
属性?
是的,UITableViewCell
自动调整大小以适合图像。 self.imageHeightConstraint
有一个 weak
引用。
尝试将其保留为strong
,因为在停用约束后它可能是nil
。
我已经尝试过了,没有任何区别。
【参考方案1】:
计算动态表格视图单元格高度相当复杂。在您的情况下,单元格高度取决于图像高度。
重用表格视图单元格时,所有单元格的属性都将被重用,高度也不例外。进行更改的简单方法是使用heightForRowAtIndexPath
,但使用自动布局计算高度时非常困难。
根据这篇文章 (http://www.raywenderlich.com/87975)。表格视图单元格中的子视图将被压缩,之后,我们可以轻松获取高度并返回heightForRowAtIndexPath
。但是,需要一点时间来计算并使您的滚动不平滑,但我们可以使用estimatedRowHeight
,您的表格视图将使用估计高度并申请特定行,然后我们才能准确计算该行的高度
以下是简短的演示代码:
//Estimate height (height could be 35, 42, 50, 29, etc)
//Just estimate a number
- (CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath
if (indexPath.row == 0)
return 40.0f;
//Your exactly height for row
- (CGFloat)calculateHeightForConfiguredSizingCell:(UITableViewCell *)sizingCell
[yourCustomCell setNeedsLayout];
[yourCustomCell layoutIfNeeded];
CGSize size = [yourCustomCell.contentView systemLayoutSizeFittingSize:UILayoutFittingCompressedSize];
return size.height;
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
//only set once
static YourCustomTableViewCell *yourCustomCell = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^
//load custom cell
yourCustomCell = (YourCustomTableViewCell*)[Utils getCellNibFile:@"YourCustomTableViewCell" Owner:self];
);
//get image from datasource
UIImage* image = [self.dataSource objectAtIndex:indexPath];
//set image for cell and begin calculate height after set image
[yourCustomCell setImage:image];
[self calculateHeightForConfiguredSizingCell:yourCustomCell];
return height;
【讨论】:
以上是关于关于单元重用的自定义 UITableViewCell 约束问题的主要内容,如果未能解决你的问题,请参考以下文章
带有 UIProgressView 的自定义 UICollectionViewCell 在重用单元格上显示 progressView
UITableView 可重用的自定义单元格在子视图中显示错误的内容
来自笔尖的自定义 UiTableViewCell 没有重用?