Ios 如何知道UITableViewCell何时完成其自动布局过程

Ios 如何知道UITableViewCell何时完成其自动布局过程,ios,uitableview,autolayout,Ios,Uitableview,Autolayout,我为一个单元格提供一些文本和图像的URL。 使用imageFromURL:方法显示图像的ImageView是一个自定义类,它在内部查看自己的大小并向URL追加查询,如: .com/img.png?ver=200&hor=500 然后,服务器计算返回哪个大小的图像以获得最佳结果 这意味着我需要自动布局来布局imageView,然后才有文本以外的任何内容。在保证imageView具有其最终大小后,我调用imageWithURL:方法 我构建的自动布局填充了我的文本标签,因为单元格高度是固定

我为一个单元格提供一些文本和图像的URL。 使用
imageFromURL:
方法显示图像的ImageView是一个自定义类,它在内部查看自己的大小并向URL追加查询,如:

.com/img.png?ver=200&hor=500
然后,服务器计算返回哪个大小的图像以获得最佳结果

这意味着我需要自动布局来布局imageView,然后才有文本以外的任何内容。在保证imageView具有其最终大小后,我调用
imageWithURL:
方法

我构建的自动布局填充了我的文本标签,因为单元格高度是固定的,所以它决定了图像的剩余内容。(一些抗压性、最小尺寸等都包括在内——这一切都有效,我在下面的代码中省略了它)

我从
layoutSubviews:
记录的内容是:

  • {0,0}//第一次
  • {320498}//现在看起来不错-可以调用imageWithURL:now
  • {320498}//计算单元格或表视图可能需要额外一个 身高
我的目标是确定何时完成布局,我可以调用我的
setImageWithURL:
,并为imageView设置正确的大小。 layoutSubviews似乎是我唯一可以链接到该信息的地方,但我真的觉得在layoutSubviews中添加这样的代码并将数据更新混入我的布局代码中很不舒服:

if (_imageView.frame.size.width == 0)
    [_imageView setImageWithURL:_propertyWithURL];
此外,根据上面的日志记录,会将我的图像设置为LayoutSubView的2倍,这称为多次

所以,希望有人能帮我把这些电话的顺序弄对,或者建议一种不同的方法来达到这个效果


提前感谢。

首先,使用
viewdilayoutsubviews
检测视图何时完成子视图的布局

其次,有时甚至会自动多次调用
viewdilayoutsubviews
。如果要确保只设置一次图像,可以添加一个类变量,例如
bool viewLaidout
,在
viewdiload
中将其初始化为
NO
,仅在
viewdilayoutsubviews
中设置图像,如果
viewLaidout==NO
,则在
viewdilayoutsubviews
的第一步中,设置图像并将
viewLaidout
设置为
YES
,例如:

bool viewLaidout;

- (void)viewDidLoad {
    viewLaidout = NO;
}

- (void)viewDidLayoutSubviews {
    if (viewLaidout == NO) {
        [_imageView setImageWithURL:_propertyWithURL];
        viewLaidout = YES;
    }
}

您不需要在init中显式调用
setNeedsUpdateConstraints
。这可能会导致双重布局调用。还有一个很好的机会是,
layoutSubviews
会被频繁调用,因为这是在
updateConstraints
之后调用的方法,以便除了将布局标记为脏的任何其他操作之外,还设置每个视图的帧。但是,这将是检查自动布局过程结果的帧的正确位置,因为这是您感兴趣的

有几种方法可以处理此问题:

部队布局 如果您知道视图约束已安装,并且希望立即强制进行布局传递,则可以将视图的布局标记为脏,并调用
layoutifneed

[self setNeedLayout];
[self layoutIfNeeded];
CGSize imageSize = self.imageView.bounds.size;
请谨慎使用此方法,因为它基本上是在您要求系统进行布局时强制系统进行布局。通常情况下,您希望允许系统根据需要进行布局,因为使用自动布局可能会很昂贵

仅在更改时更新图像 另一种方法是,让系统像正常一样处理布局,同时仍在
布局子视图中检查图像视图的框架,但仅当图像大小与您已设置的图像大小不同时,才获取新图像。这将为您提供在本例中要查找的结果,因为图像视图的大小在后两个过程中是相同的。这还允许图像视图更改大小并仍能获得更新的图像:

if (CGSizeEqualToSize(self.imageView.bounds.size, self.lastImageViewSize) == NO) {
  //fetch new image from server
}

此外,请确保您请求的图像分辨率为视网膜显示器的两倍。您可以使用
UIScreen
上的
scale
属性获取屏幕比例,并将每个维度乘以该值以进行一般处理。如果您不需要构建多个屏幕,只需使用
[[UIScreen mainScreen]缩放]

谢谢Lyndsey。viewDidLayoutSubviews是(表)viewController上的一种方法。我是否需要构建一些可见的witch单元格映射,然后更新那里的URL?我遇到了完全相同的问题。你最后是怎么解决的?
if (CGSizeEqualToSize(self.imageView.bounds.size, self.lastImageViewSize) == NO) {
  //fetch new image from server
}