我提供的单元格包含一些文字和图片的网址。
使用imageFromURL:
方法显示图像的ImageView是一个自定义类,它在内部查看自己的大小并向URL附加查询,如:
.com/img.png?ver=200&hor=500
服务器然后确定要返回的大小图像以获得最佳结果。
这意味着我需要AutoLayout在除了文本之外的任何内容之前布局imageView。在我保证imageView具有其最终大小后,我调用imageWithURL:
方法。
我构建的autolayout填充了我的textLabel,由于单元格高度是固定的,因此它决定了图像的剩余部分。 (一些抗压缩性,最小尺寸等等 - 这一切都有效,我从下面的代码中省略了它。)
- (id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
/*
stuff that goes into making the cell ready
.
.
.
*/
[self setNeedsUpdateConstraints];
return self;
}
- (void)updateConstraints
{
/*
first set the different constraints
.
.
.
then call super
*/
[super updateConstraints];
}
- (void) updateCellWithText:(NSString*) text andImageURL:(NSURL*) imgURL
{
self.textLabel.text = text;
[self.imageView setImageWithURL:imgURL];
//calling setNeedsUpdateConstraints here won't help much as there is still not a correct size
}
- (void) layoutSubviews
{
[super layoutSubviews];
NSLog(@"%@", NSStringFromCGSize(self.imageView.frame.size));
}
我从layoutSubviews:
登录的是:
我的目标是弄清楚我们何时完成布局,并且可以使用正确大小的imageView调用我的setImageWithURL:
。
layoutSubviews似乎是唯一可以嵌入此信息的地方 - 但我真的觉得在将这样的代码添加到layoutSubviews并将我的数据更新混合到我的布局代码中时感到很不舒服:
if (_imageView.frame.size.width == 0)
[_imageView setImageWithURL:_propertyWithURL];
同样来自上面的日志记录会导致我的图像被设置2次,因为layoutSubviews被多次调用。
所以,希望有人可以帮助我正确地获得这些电话的顺序,或建议采用不同的方法来实现结果。
提前致谢。
答案 0 :(得分:2)
您不需要在init中显式调用setNeedsUpdateConstraints
。此可能导致双重布局调用。还有一个非常好的机会layoutSubviews
将被频繁调用,因为这是在updateConstraints
之后调用的方法,以便除了标记布局的任何其他操作之外还设置每个视图的帧脏了。但是,这将是检查自动布局传递结果的帧的正确位置,因为这是您感兴趣的内容。
有几种方法可以解决这个问题:
如果知道已经安装了视图约束,并且您想强制布局立即传递,则可以将视图的布局标记为脏并调用{ {1}}:
layoutIfNeeded
谨慎使用此方法,因为它基本上是在您告诉系统时强制系统进行布局。通常,您希望允许系统根据需要进行布局,因为使用自动布局布局可能很昂贵。
另一种方法是让系统在正常情况下处理布局,同时仍然在[self setNeedLayout];
[self layoutIfNeeded];
CGSize imageSize = self.imageView.bounds.size;
中检查图像视图的帧,但是如果图像的大小与您的图像大小不同,则仅获取新图像已经开始了。在这种情况下,这将为您提供您正在寻找的结果,因为图像视图的大小在后两次传递中是相同的。这也允许图像视图更改大小并仍然获得更新的图像:
layoutSubviews
另外 - 确保您要求双倍分辨率的图像用于视网膜显示。您可以使用if (CGSizeEqualToSize(self.imageView.bounds.size, self.lastImageViewSize) == NO) {
//fetch new image from server
}
上的scale
属性获取屏幕比例,并将每个维度乘以该值来统一处理它。如果您不是为多个屏幕构建,请使用UIScreen
答案 1 :(得分:1)
首先,使用viewDidLayoutSubviews
检测视图何时完成布局子视图。
其次,有时甚至viewDidLayoutSubviews
会被多次自动调用。如果你想确保你只设置一次图像,也许可以添加一个类变量,例如。 bool viewLaidout;
,将其初始化为NO
中的viewDidLoad
,仅在viewDidLayoutSubviews
viewLaidout == NO
中设置图片,然后在viewDidLayoutSubviews
的第一遍中,设置图片并将viewLaidout
设置为YES
,例如:
bool viewLaidout;
- (void)viewDidLoad {
viewLaidout = NO;
}
- (void)viewDidLayoutSubviews {
if (viewLaidout == NO) {
[_imageView setImageWithURL:_propertyWithURL];
viewLaidout = YES;
}
}