我有一个带有ImageView
的TableViewCell
,我正在设置图像:
[self.contentImageView setImageWithURL:thumbnail_url];
contentMode
设置为UIViewContentModeScaleAspectFill
,子视图被剪裁。 这最适合纵向或横向图像,但实际上UIViewContentModeScaleToFill
更适合横向图像,这些图像要丰富得多。
因此,我想通过比较宽度和高度来检测图像的方向,并相应地更改contentMode
。
起初,我尝试检查/记录ImageView.image
属性,在我从 url 设置它之后直接使用它,但它显示 nil。不知道为什么...?
接下来,我决定将该NSURL
放入NSData
对象中,然后从该数据创建一个UIImage
,并使用该 iVaR 设置ImageView
的图像属性,如下所示:
NSData *data = [NSData dataWithContentsOfURL:thumbnail_url];
UIImage *image = [UIImage imageWithData:data];
[self.contentImageView setImage:image];
// Get image.size etc.
这 - 特别是NSData
调用 - 大大减慢了TableViewCell's
的加载速度,所以我想避免它。
所以,我想知道在缩放发生在contentMode
之前,是否有任何方法可以进入ImageView
的未裁剪源图像属性?
这里的问题是你对第一种方法如何工作的误解。setImageWithURL:
是来自开源图像加载库之一的方法。可能是AFNetworking或SDWebImage。
这些方法是异步的,并立即返回。他们在后台队列上下载图像,然后返回到主队列以使用它设置视图。您正在尝试在下载image
之前访问该。手动NSData
方法起作用的原因是因为它是同步的,并且在下载映像时主队列停滞不前。
我提到的两个库都有单独的方法,主队列上有一个回调块,允许您对响应进行操作。
对于AFNetworking,您可以使用此方法:
- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
placeholderImage:(UIImage *)placeholderImage
success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success
failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure;
对于 SDWebImage,您可以使用此方法:
- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;
在这两种情况下,回调块将允许您在下载图像后访问图像(如果成功)。
您也可以使用 GCD 手动使用dataWithContentsOfURL:
方法完成类似操作的内容,如下所示:
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^()
{
NSData *data = [NSData dataWithContentsOfURL:thumbnail_url];
UIImage *image = [UIImage imageWithData:data];
dispatch_async(dispatch_get_main_queue(), ^()
{
[self.contentImageView setImage:image];
});
});
这是网络中使用的一种基本模式,用于在更新主队列上的视图之前在后台队列上执行网络请求和处理。请记住,这段特定的代码非常简单,需要更多的工作才能像我上面提到的库一样好地工作。