我正在使用它来通过JSON解析到tableView来显示一些标签和图像,但是当滚动tableview图像来到并跳舞时,图像不会出现在第一次启动时我的意思是不按顺序格式帮助我这个
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
self.customCellClass = [tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (self.customCellClass == nil)
{
self.customCellClass = [[CellCustom alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}
self.customCellClass.nameLabel.text = [[arrayData objectAtIndex:indexPath.row] objectForKey:@"name"]; // label
self.customCellClass.cityLabel.text = [[arrayData objectAtIndex:indexPath.row] objectForKey:@"region"]; // label
NSString * stripped = [[[arrayData objectAtIndex:indexPath.row] objectForKey:@"summary"] stripHtml]; //label
self.customCellClass.detailLabel.text = stripped;
self.customCellClass.mainImage.image = nil;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
NSData *data0 = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[[arrayData objectAtIndex:indexPath.row]objectForKey:@"images"]objectForKey:@"logo"]]];
UIImage *image = [UIImage imageWithData:data0];
dispatch_sync(dispatch_get_main_queue(), ^(void) {
self.customCellClass.mainImage.image = image;
});
});
return self.customCellClass;
}
答案 0 :(得分:0)
使用UITableView's
cellForRowAtIndexPath
方法替换以下代码:
//Check if cell has image or not
if(!self.customCellClass.mainImage.image)
{
dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(q, ^{
NSData *data0 = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[[arrayData objectAtIndex:indexPath.row]objectForKey:@"images"]objectForKey:@"logo"]]];
UIImage *image = [UIImage imageWithData:data0];
//Get main queue
dispatch_async(dispatch_get_main_queue(), ^{
/* This is the main thread again, where we set the tableView's image to be what we just fetched. */
self.customCellClass.mainImage.image = image;
});
});
}
良好的解决方案,如果您使用的是AFNetworking,那么请使用UIImageView+AFNetworking
类别
NSURL *imageURL = [NSURL URLWithString:[[[arrayData objectAtIndex:indexPath.row]objectForKey:@"images"]objectForKey:@"logo"]]
[self.customCellClass.mainImage setImageWithURL:imageURL placeholderImage:nil];
答案 1 :(得分:0)
每次加载单元格并下载相同的图像时,都会指定image = nil。
您可以使用以下课程来无缝地执行此操作。
AsyncImageView.h
#import <UIKit/UIKit.h>
@interface AsyncImageView : UIView {
NSURLConnection *connection;
NSMutableData *data;
NSString *urlString; // key for image cache dictionary
}
-(void)loadImageFromURL:(NSURL*)url;
-(void)loadBackgroundImage:(UIImage *)image;
-(UIImage*)loadImageFromURLForGetIamge:(NSURL*)url;
-(BOOL)getCachedImageWithUrl:(NSString*)url;
@end
和AsyncImageView.m
#import "AsyncImageView.h"
#import "ImageCacheObject.h"
#import "ImageCache.h"
//
// Key's are URL strings.
// Value's are ImageCacheObject's
//
static ImageCache *imageCache = nil;
#define SPINNY_TAG 5555
@implementation AsyncImageView
- (id)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
}
return self;
}
- (void)drawRect:(CGRect)rect {
// Drawing code
}
- (void)dealloc {
[connection cancel];
}
-(void)loadBackgroundImage:(UIImage *)image
{
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.layer.masksToBounds=YES;
//imageView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self addSubview:imageView];
imageView.frame = self.bounds;
[imageView setNeedsLayout];
[self setNeedsLayout];
imageView=nil;
}
-(void)loadImageFromURL:(NSURL*)url
{
if (connection != nil) {
[connection cancel];
connection = nil;
}
if (data != nil) {
data = nil;
}
if (imageCache == nil) // lazily create image cache
imageCache = [[ImageCache alloc] initWithMaxSize:2*1024*1024]; // 2 MB Image cache
// NSLog(@"Value of the url here = %@",url);
urlString = [[url absoluteString] copy];
UIImage *cachedImage = [imageCache imageForKey:urlString];
if (cachedImage != nil)
{
if ([[self subviews] count] > 0)
{
[[[self subviews] objectAtIndex:0] removeFromSuperview];
}
UIImageView *imageView = [[UIImageView alloc] initWithImage:cachedImage];
imageView.contentMode = UIViewContentModeScaleAspectFill;
imageView.layer.masksToBounds=YES;
[self addSubview:imageView];
imageView.frame = self.bounds;
[imageView setNeedsLayout]; // is this necessary if superview gets setNeedsLayout?
[self setNeedsLayout];
imageView=nil;
return;
}
UIActivityIndicatorView *spinny = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinny.tag = SPINNY_TAG;
spinny.frame=CGRectMake(self.frame.size.width/2-10, self.frame.size.height/2-10, 20, 20);
spinny.center = self.center;
[spinny startAnimating];
[self addSubview:spinny];
[self bringSubviewToFront:spinny];
spinny=nil;
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:60.0];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
}
-(BOOL)getCachedImageWithUrl:(NSString*)url
{
BOOL isIamgeCached=NO;
if (imageCache == nil)
imageCache = [[ImageCache alloc] initWithMaxSize:2*1024*1024]; // 2 MB Image cache
UIImage *cachedImage = [imageCache imageForKey:url];
if (cachedImage != nil)
{
isIamgeCached=YES;
}
return isIamgeCached;
}
-(UIImage*)loadImageFromURLForGetIamge:(NSURL*)url
{
if (connection != nil)
{
[connection cancel];
connection = nil;
}
if (data != nil)
{
data = nil;
}
if (imageCache == nil) // lazily create image cache
imageCache = [[ImageCache alloc] initWithMaxSize:2*1024*1024]; // 2 MB Image cache
// NSLog(@"Value of the url here = %@",url);
urlString = [[url absoluteString] copy];
UIImage *cachedImage = [imageCache imageForKey:urlString];
if (cachedImage != nil)
{
if ([[self subviews] count] > 0)
{
[[[self subviews] objectAtIndex:0] removeFromSuperview];
}
UIImageView *imageView = [[UIImageView alloc] initWithImage:cachedImage];
imageView.contentMode = UIViewContentModeScaleToFill;
imageView.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self addSubview:imageView];
imageView.frame = self.bounds;
[imageView setNeedsLayout]; // is this necessary if superview gets setNeedsLayout?
[self setNeedsLayout];
imageView=nil;
return cachedImage;
}
UIActivityIndicatorView *spinny = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
spinny.tag = SPINNY_TAG;
spinny.frame=CGRectMake(self.frame.size.width/2-10, self.frame.size.height/2-10, 20, 20);
//spinny.center = self.center;
[spinny startAnimating];
[self addSubview:spinny];
[self bringSubviewToFront:spinny];
spinny=nil;
NSURLRequest *request = [NSURLRequest requestWithURL:url
cachePolicy:NSURLRequestUseProtocolCachePolicy
timeoutInterval:20.0];
connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
return cachedImage;
}
- (void)connection:(NSURLConnection *)connection
didReceiveData:(NSData *)incrementalData {
if (data==nil)
{
data = [[NSMutableData alloc] initWithCapacity:2048];
}
[data appendData:incrementalData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)aConnection
{
connection = nil;
UIView *spinny = [self viewWithTag:SPINNY_TAG];
[spinny removeFromSuperview];
if ([[self subviews] count] > 0)
{
[[[self subviews] objectAtIndex:0] removeFromSuperview];
}
UIImage *image = [UIImage imageWithData:data];
[imageCache insertImage:image withSize:[data length] forKey:urlString];
UIImageView *imageView = [[UIImageView alloc]
initWithImage:image];
imageView.contentMode = UIViewContentModeScaleToFill;
imageView.autoresizingMask =
UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
[self addSubview:imageView];
imageView.frame = self.bounds;
[imageView setNeedsLayout]; // is this necessary if superview gets setNeedsLayout?
[self setNeedsLayout];
imageView=nil;
data = nil;
}
@end
答案 2 :(得分:0)
使用dispatch_async
从远程加载图像,这意味着要在tableview单元格中显示的图像是异步加载的。并且您使用实例变量来记录当前单元格,这会导致您遇到的问题。
加载图像完成后(可能需要几分钟),它希望显示在单元格中(用此代码编写),
dispatch_sync(dispatch_get_main_queue(), ^(void) {
self.customCellClass.mainImage.image = image;
});
仅发现self.customCellClass
指向错误的单元格(- (UITableViewCell *)cellForRowAtIndexPath:(NSIndexPath *)indexPath
在加载图像期间被多次调用,并且每次调用都将self.customCellClass
的指向更改为其他单元格)。
因此,图像的顺序是错误的。
试试这个:
使用位置变量使单元格从dequeueReusableCellWithIdentifier
开始。像这样:
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath: (NSIndexPath *)indexPath
{
CellCustom *customCellClass = (CellCustom *)[tableView dequeueReusableCellWithIdentifier:@"Cell"];
if (customCellClass == nil)
{
customCellClass = [[CellCustom alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
}
customCellClass.nameLabel.text = [[arrayData objectAtIndex:indexPath.row] objectForKey:@"name"]; // label
customCellClass.cityLabel.text = [[arrayData objectAtIndex:indexPath.row] objectForKey:@"region"]; // label
NSString * stripped = [[[arrayData objectAtIndex:indexPath.row] objectForKey:@"summary"] stripHtml]; //label
customCellClass.detailLabel.text = stripped;
customCellClass.mainImage.image = nil;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^(void) {
NSData *data0 = [NSData dataWithContentsOfURL:[NSURL URLWithString:[[[arrayData objectAtIndex:indexPath.row]objectForKey:@"images"]objectForKey:@"logo"]]];
UIImage *image = [UIImage imageWithData:data0];
dispatch_sync(dispatch_get_main_queue(), ^(void) {
customCellClass.mainImage.image = image;
});
});
return customCellClass;
}
此外,请查看- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier
和- (id)dequeueReusableCellWithIdentifier:(NSString *)identifier forIndexPath:(NSIndexPath *)indexPath
之间的区别。