如何对UITableViewCell宽度变化作出反应?

时间:2017-09-08 10:43:56

标签: ios objective-c uitableview

我正在开发iOS 9+应用。 UITableViewCell子类包含一个子视图,该子视图充当另一个"类似于进度条的"视图:

UITableViewCell (content View)
+---------------------------------------------+
|  ContainerView (# = Progress View)          |
|  +--------------------------------------+   |                                               
|  |##############                        |   |
|  +--------------------------------------+   |  
|                                             |
+---------------------------------------------+

因此,ContainerView用于将ProgressView定位在单元格内。

ProgressView 是真正的进度条,只是UIView,宽度应该用于表示某些进度。它使用Top,Bottom和Leading约束定位到ContainerView。宽度使用固定值约束定义。

因此将进度设置为某个值x只是意味着设置width-constraint的常量:

// Set progress to .75
ProgressCell * cell = [self.tableView dequeueReusableCellWithIdentifier:kProgressCellID];
if (cell == nil)
    cell = [[ProgressCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:kProgressCellID];

cell.progress = 0.75;


// ProgressCell.m
- (void)setProgress:(float)value {
    _progress = value;
    CGFloat width = self.progressContainerView.frame.size.width * _progress;
    self.progressWidthConstraint.constant = width;
}

这种方法一般都很好,但在大多数情况下它不起作用:

  • UITableView已加载,tableView:cellForRowAtIndexPath:被称为
  • 创建或出列单元格
  • 设置进度值。此时TableView和Cells的宽度似乎是默认宽度320px。
  • 在加载页面(和所有单元格)之后,将TableView和所有单元格重新调整为实际设备宽度,例如。 375px。
  • 显然,320%的x%不是37%的x%。因此,应在调整大小时更新进度约束。

有时,单元格的加载宽度正确。这似乎是某种竞争条件(在最终宽度设定之前或之后创建单元格)。

我尝试在cels layoutSubviews中手动重新加载进度/宽度,但这也不起作用。

知道如何解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

即使我在使用自动布局时遇到同样的问题。

在计算和设置进度之前尝试使用以下代码

[cell setNeedsUpdateConstraints];
    [cell updateConstraintsIfNeeded];

    cell.bounds = CGRectMake(0.0f, 0.0f, CGRectGetWidth(self.initiativeMetricTableView.bounds), CGRectGetHeight(cell.bounds));
    cell.contentView.bounds = cell.bounds;
    [cell setNeedsLayout];
    [cell layoutIfNeeded];

希望这会有所帮助。

答案 1 :(得分:1)

我的建议是每当单元格的帧发生变化时调用setProgress setter(或刷新progressContainerView框架的新方法)。例如。您可以在ProgressCell子类中执行以下操作

- (void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
    [self setProgress:_progress];
}