要查看问题的演示以及代码,请have a look at the following 60 second video.
Here is a simple project demonstrating the problem。 挑战,看看你是否可以在运行时使用我创建的类别触摸tableviewcontroller来显示图像。
我创建了一个简单的UIImageView
类别,其中我公开了一个imageURL
属性,该属性在设置时应该开始异步下载。调用完成块后,我将类“image
属性设置为下载的图像。
然后我有一个继承自UITableViewController
的类,我在其中导入自定义UIImageView
类别。我通过设置单元格的imageview willDisplayCell:
属性,在imageURL
方法中开始下载。图像是异步下载并设置的,但是除非我将单元格从表格中滚动,否则单元格的imageview不会更新,或者我单击单元格本身。
我尝试了[self setNeedsDisplay];
之类的内容以及其他一些内容,例如在主线程上执行图像的设置,但都无济于事。
有人可以看看,让我知道我应该做什么吗?
一些代码:
的UIImageView + AsyncDLImageView.h
#import <UIKit/UIKit.h>
@interface UIImageView (AsyncDLImageView)
@property (nonatomic, retain) NSURL *imageURL;
@end
的UIImageView + AsyncDLImageView.m
#import "UIImageView+AsyncDLImageView.h"
@implementation UIImageView (AsyncDLImageView)
- (void)setImageURL:(NSURL *)imageURL{
[self loadImageWithURL:imageURL completionHandler:^(UIImage *image, NSError *error) {
if(!error) {
NSLog(@"image has been set: %@", image);
self.image = image;
}
}];
}
-(NSURL *)imageURL{
return self.imageURL;
}
-(void)loadImageWithURL:(NSURL*)url completionHandler:(void(^)(UIImage *image, NSError *error))completionBlock{
NSLog(@"set image url request called: %@", [url absoluteString]);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
{
NSLog(@"no error");
UIImage *image = [[UIImage alloc] initWithData:data];
completionBlock(image, nil);
} else{
completionBlock(nil, error);
NSLog(@"error");
}
}];
}
答案 0 :(得分:0)
看起来因为表格单元格上的imageView没有初始化,所以图像不会显示。我添加了一个透明的placeHolder图像(使您想要图像的大小)并在等待图像加载时使用它。 (这对我有用)
所以我改变了代码如下......
DisplayXMLImageDataTVC.m
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [_xmlImageURLArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *cellIdentifier = @"xmlCellIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if(cell == nil){
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
cell.imageView.image = [UIImage imageNamed:@"placeHolder"];
}
[cell.imageView setImageURL:[_xmlImageURLArray objectAtIndex:indexPath.row]];
return cell;
}
和您的类别类回到原来的状态....
- (void)setImageURL:(NSURL *)imageURL
{
// objc_setAssociatedObject(self, @selector(imageURL), imageURL, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
[self loadImageWithURL:imageURL completionHandler:^(UIImage *image, NSError *error) {
if(!error) {
self.image = image;
}
}];
}
-(void)loadImageWithURL:(NSURL*)url completionHandler:(void(^)(UIImage *image, NSError *error))completionBlock{
NSLog(@"set image url request called: %@", [url absoluteString]);
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
if ( !error )
{
NSLog(@"no error");
UIImage *image2 = [[UIImage alloc] initWithData:data];
completionBlock(image2, nil);
} else{
completionBlock(nil, error);
NSLog(@"error");
}
}];
}
答案 1 :(得分:0)
原因是在设置图像后不重绘单元格。通常我们会在cellForRowAtIndexPath
中发送图像的异步请求,在我们获取图片后,我们会调用单元格setNeedsLayout
。
所以你可以做到以下几点。
- (void)setImageURL:(NSURL *)imageURL
{
UITableViewCell *cell = (UITableViewCell *)self.superview.superview;
[self loadImageWithURL:imageURL completionHandler:^(UIImage *image, NSError *error) {
if(!error) {
NSLog(@"image has been set: %@", image);
self.image = image;
[cell setNeedsLayout];
}
}];
}
答案 2 :(得分:0)
问题似乎是UITableViewCell使用imageView的初始帧来布局单元格。如果未设置,则获得0x0帧,即使稍后设置图像,帧也不会更改。如果将其设置为某个占位符图像,则会继续使用该占位符图像中的帧,这可能不是您想要的。
一个可能的解决方案是拥有一个自定义UITableViewCell,它会覆盖layoutSubviews并根据您拥有的图像设置框架。从您的imageView类别,在设置图像后,调用[self setNeedsLayout]。这将导致在下次重绘时调用layoutSubviews。
你也可以看一下 - http://www.wrichards.com/blog/2011/11/sdwebimage-fixed-width-cell-images/