第一次从错误的大小类报告UIView的自动布局大小

时间:2016-05-13 19:28:10

标签: ios objective-c uiview autolayout size-classes

我有一个UITableViewController,其中包含一些自定义单元格和每个单元格中的UIView。我已经实现了控制器的cellForRowAtIndexPath来配置每个单元格中的UIView。为此,我需要知道屏幕上UIView的宽度。由于我使用autolayout和size类来根据设备方向自动更改UIView的大小,因此我实现了另一种获取宽度运行时的方法。

问题在于,当第一次显示表视图时,即使我在横向使用设备时,我的代码也会从紧凑的宽度尺寸类报告UIVIew的宽度。系统渲染所有视图,但我的代码获取宽度不起作用。滚动新单元格可见或方向更改将立即解决问题。

我的代码:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 

            // ...

            CustomCell* cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCell"];

            if (cell == nil) {
                NSArray *nib = [[NSBundle mainBundle] loadNibNamed:@"CustomCell" owner:self options:nil];
                cell = [nib firstObject];
            } else {

                // Clear custom content

                NSArray *viewsToRemove = [cell.histogramView subviews];
                for (UIView *v in viewsToRemove) {
                    [v removeFromSuperview];
                }
            }

            [cell setNeedsLayout];
            [cell layoutIfNeeded];

            int width = ((CustomView*)cell.customView).getWidth;
            NSLog(@"width = %d", width);

            // ...

}

然后:

@implementation CustomView

- (int)getWidth {
    [self setNeedsLayout];
    [self layoutIfNeeded];

    int width = self.frame.size.width;
    return width;
}

@end

编辑添加:

问题似乎是在第一次出现tableview时调用cellForRowAtIndexPath时,单元格没有发生autolayout。在创建单元格后立即使用[cell setNeedsLayout]和[cell layoutIfNeeded]强制它也不会起作用。

似乎我的问题根本原因是How to know the width of an UITableViewCell when using auto layout?的潜在重复因此问题与以下事实有关:当我的CustomCell从nib加载时,它将具有默认帧。应该采取特殊措施强制自动布局。但是,接受的答案不适用于最初超出可见区域的单元格。对此有何看法?

2 个答案:

答案 0 :(得分:0)

我建议尝试使用约束和比率而不是框架的实际宽度,因为正如Marcus Adams所说,框架将具有您实际只在viewDidAppear之后寻找的值。

例如,如果您的单元格包含的单元格宽度为1/3的UILabel,以及填充剩余空间的UIImageView,则可以在它们与父视图之间设置约束。

你的逻辑可以像这样改变吗?

另一个建议是在viewDidAppear之后在你的表视图上调用reloadData,但这绝对不是一个很好的选择UX。

答案 1 :(得分:0)

我找到了正确的解决方案:

  1. 像原始问题一样创建自定义单元格。
  2. cell.contentMode = UIViewContentModeRedraw
  3. 中设置tableview: cellForRowAtIndexPath:
  4. 为自定义单元格实现layoutSubviews,如下所示:

    - (void)layoutSubviews { [super layoutSubviews]; NSLog(@"cell width == %f", self.bounds.size.width); }

  5. 通过这种方式,您可以访问屏幕上显示的单元格大小。