使用AFNetworking2.0的方法setImageWithUrl,我在位于UITableViewCell中的imageView中设置了一张图片。当显示的图像第一次被下载,然后设置时,它工作得很好。但是,如果在设置时,图片在本地可用(已被缓存),则在显示之前会有快速的白闪。
你知道如何避免这种情况吗?
重现的步骤。
设置图像的代码。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
myCell *cell = (myCell *)[tableView dequeueReusableCellWithIdentifier:@"imageCell"];
[cell.myImageView setImageWithURLRequest:[NSURLRequest requestWithURL:myImageUrl] placeholderImage:nil success:^(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image) {
cell.myImageView.image = image;
} failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(@"Failed");
}];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
如果有人碰到同样的问题,我是这样解决的。
在成功区块中,替换
cell.myImageView.image = image;
与
if (request) {
[UIView transitionWithView:cell.myImageView
duration:0.8f
options:UIViewAnimationOptionTransitionCrossDissolve
animations:^{[cell.myImageView setImage:image];}
completion:NULL];
}else{
[cell.myImageView setImageWithURL:myImageURL];
}
瞧,再也没有丑陋的闪光了!
归功于 本回答 感谢你把我引向正确的方向。
看来您的问题是与单元格重用有关,而不是与缓存问题有关。
当您的单元格被重用时(当滚动的时候)。UITableView
或重新打开应用程序)它们持有对旧图像的引用。而当你通过 nil
至 placeholderImage
参数,AFNetworking不会重置您的图像。这里是 源码. 所以新的图像设置在 success
块。但是这个块可能会在轻微的网络延迟后被调用,使你的图像闪光。顺便说一下,你可以省略成功块,这样AFNetworking就会被调用。独树一帜.
如果你没有placeHolder图像,你应该设置 myImageView.image
到 nil
在试图异步设置一个新的之前。
此外,您应该检查 dequeueReusableCellWithIdentifier:
方法返回一个单元格,如果没有,则创建一个新的单元格。这可能发生在 UITableView
是第一次创建。
下面是一个例子。
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
myCell *cell = (myCell *)[tableView dequeueReusableCellWithIdentifier:@"imageCell"];
// Check if reused cell was returned.
// If not create a new one, otherwise, reset the state of the reused cell
if (!cell) {
cell = [[myCell alloc] init];
} else {
cell.myImageView.image = nil;
}
[cell.myImageView
setImageWithURLRequest:[NSURLRequest requestWithURL:myImageUrl]
placeholderImage:nil
success:nil
failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error) {
NSLog(@"Failed");
}];
cell.selectionStyle = UITableViewCellSelectionStyleNone;
return cell;
}
你需要一个这样的函数
BOOL ImageDataHasPNGPreffix(NSData *data) {
NSUInteger pngSignatureLength = [kPNGSignatureData length];
if ([data length] >= pngSignatureLength) {
if ([[data subdataWithRange:NSMakeRange(0, pngSignatureLength)] isEqualToData:kPNGSignatureData]) {
return YES;
}
}
return NO;
}
然后当你保存数据时,你需要选择正确的方式来缓存。
//Saving data
if ([imageData length] >= [kPNGSignatureData length]) {
imageIsPng = ImageDataHasPNGPreffix(imageData);
}
if (imageIsPng) {
data = UIImagePNGRepresentation(image);
}
else {
data = UIImageJPEGRepresentation(image, (CGFloat)1.0);
}