iPhone-在NSURL连接完成之前,使UITableViewCells显示在视图加载上
我正在尝试使用故事板和JSON创建一个松散版本的懒散图像。在主TableViewController上的ViewDidLoad中,我启动一个NSURLConnection以获取JSON数据,但我的单元格直到连接完成后才加载。我想要与LazyTableImages相同的行为,单元格加载为空白,但随后填充信息(重新加载表数据)。如果我不使用故事板,我可以复制它,因为LazyTables不使用故事板,但这不是一个选项 我浏览了一些懒散的图片,试图找到解决方案,但故事板(对我来说)起了很大的作用 有没有一种简单的方法让电池作为空白加载?例如,如果设备没有internet,我仍然希望显示我的TableView,并且我将在单元格中放置一条自定义消息 代码: viewDidLoad中初始化连接的部分iPhone-在NSURL连接完成之前,使UITableViewCells显示在视图加载上,iphone,uitableview,nsurlconnection,Iphone,Uitableview,Nsurlconnection,我正在尝试使用故事板和JSON创建一个松散版本的懒散图像。在主TableViewController上的ViewDidLoad中,我启动一个NSURLConnection以获取JSON数据,但我的单元格直到连接完成后才加载。我想要与LazyTableImages相同的行为,单元格加载为空白,但随后填充信息(重新加载表数据)。如果我不使用故事板,我可以复制它,因为LazyTables不使用故事板,但这不是一个选项 我浏览了一些懒散的图片,试图找到解决方案,但故事板(对我来说)起了很大的作用 有没有
NSURLRequest *urlrequest = [NSURLRequest requestWithURL:[NSURL URLWithString:serverURL]];
self.dataConnection = [[NSURLConnection alloc] initWithRequest:urlrequest delegate:self];
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
连接正在加载
- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
//ListData below is an array that my data received (JSON) is loaded into. It is then passed to getTableData.
self.dataConnection = nil;
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self performSelectorOnMainThread:@selector(getTableData:) withObject:ListData waitUntilDone:YES];
});
}
getTableData
-(void)getTableData:(NSData *)jsonData
{
NSError *error = nil;
arrayEntries = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableLeaves error:&error];
for (int x = 0; x < arrayEntries.count; x++)
{
NSMutableDictionary *dic = [arrayEntries objectAtIndex:x];
//ARecord is a class just like in LazyTableImages that creates objects to keep the icons/data together. The ARecords are loaded into the TableView
ARecord *arecord = [[ARecord alloc] init];
NSString *title = [dic objectForKey:@"title"];
NSString *subt = [dic objectForKey:@"subtitle"];
NSString *url = [dic objectForKey:@"image_URL"];
arecord.Icon = nil;
arecord.URL = url;
arecord.Name = title;
arecord.title = subt;
//this is where I load an array full of the arecord objects.
[array addObject:arecord];
}
[self.tableView reloadData];
}
-(void)getTableData:(NSData*)jsonData
{
n错误*错误=nil;
arrayEntries=[NSJSONSerialization JSONObjectWithData:jsonData选项:NSJSONReadingMutableLeaves错误:&error];
对于(int x=0;x
由于我没有看到您的代码,我只在这里给出我的建议:
- (void)viewDidLoad
{
[super viewDidLoad];
dispatch_queue_t queue = dispatch_queue_create(NULL, NULL);
dispatch_async(queue, ^{
//add your connection code here
//parse the json and store the data
//
dispatch_async(dispatch_get_main_queue(), ^{
//here to reload your table view again,
//since UI related method should run on main thread.
[YOUR_TABLEVIEW reloadData];
});
});
[YOUR_TABLEVIEW reloadData];
}
注意:确保序列图像板中的tableview已连接到代码中的tableview!希望有帮助 我用两个对象来实现这一点。首先,我有一个image fetcher类,它异步下载数据并在数据完成时通知委托。然后,我有一个图像视图类,它实现了fetcher的委托方法。比如:
@implementation AsyncImageFetcher
-(id)initWithURL:(NSURL *)aURL andDelegate:(id<SomeProtocol>)aDelegate{
//...
NSURLRequest *req = [NSURLRequest requestWithURL:aURL];
//Note that NSURLConnection retains its delegate until the connection
//terminates! See comments in MyImageView below.
[NSURLConnection connectionWithRequest:req delegate:self];
//...
}
//Implement standard connection delegates here. The important part is:
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
// ...
UIImage *anImage = [self decodeDownloadedDataIntoAnImage];
if([[self delegate] respondsToSelector:@selector(imageFetcher:didFetchImage:)]){
[[self delegate] imageFetcher:self didFetchImage:anImage];
}
//...
}
@end
在您的特定情况下,您只需在
-tableView:cellForRowAtIndexPath:
中将MyImageView
设置为单元格的imageView
,当然,为其占位符和URL传递合理的值。我也做了类似的事情。在viewDidLoad中:我将表数据的数组设置为[NSNull null]的几个对象,以便在下载数据时显示多少空行。在cellForRowAtIndexPath中:我检查[self.ArrayFTableData objectAtIndex:indexPath.row]=[NSNull null]。如果是,则返回一个“空白”单元格,否则用ARRecrod数据加载单元格。
然后,当URL完成时,将NSNull数组替换为Arrescords数组。您是否在主线程上调用了网络?如果是这样的话,网络会阻塞UI线程。我曾尝试使用GCD将其移出主线程,但随后我只得到一个白色屏幕,因为该表从未加载。NURLConnection中有一个GCD调用,用于处理不同线程上的JSON解析。请注意,您的NSURLConnection(应该)已经是异步的。将其移动到后台线程可能是个坏主意。正如奎因所说,就网络而言,“线程是邪恶的”™".我也记得这一点,但无论我如何剪切它;或者将NSURLConnection移动到后台线程,或者将解析移动到后台线程,直到NSURLConnection完成,单元格才会加载。我需要将初始下载移出UIs方式。您使用了asyn newworking,因此无需使用gcd。感谢您的帮助回答。我添加了代码以帮助消除任何混乱。只是花了一段时间才获得我需要的内容并正确编辑。我这样做很累,但我现在这样做是处理我的初始JSON调用的最佳方式。我在第二个类中获得图像,这只是为了获得包含URL的JSON的第一位,以获得图像稍后再同步。还有其他想法吗?谢谢,异步加载JSON也是一样。只是,不用
-decodingdowLoadedDataInAtanimage
,而是将下载的JSON数据解析为对象。不用图像作为委托,而是(大概)使用您的表的控制器,这样它就可以用新的JSON数据重新加载表了。谢谢。我一直认为这是我需要的方法,但我仍然无法让它工作。我添加了代码来帮助消除混乱。所以我尝试了这种方法,我只是挂断了调度调用。现在还有其他建议吗我没有发布一些代码吗?谢谢小心!在一个线程上进行网络连接几乎总是一个错误。工作非常完美,这正是我想要的。谢谢!
@implementation MyImageView
-(id)initWithURL:(NSURL *)aURL andPlaceHolderImage:(UIImage *)aPlaceHolder{
//...
[self setImage:aPlaceHolder];
//Note we don't assign this to an ivar or retain it or anything.
//That's ok because the NSURLConnection inside the fetcher actually
//retains the fetcher itself. So it will live until the connection
//terminates -- which is exactly what we want. Thus we disable
//CLANG's noisy warnings.
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-value"
[[AsyncImageFetcher alloc] initWithURL:aURL andDelegate:self];
#pragma clang diagnostic pop
return self;
}
-(void)imageFetcher:(MCMAsyncImageFetcher *)anImageFetcher didFetchImage:(UIImage *)anImage{
[self setImage:anImage];
}
@end