我正在创建一个应用程序,将动画UIImageView显示为指示应用程序正忙的自定义方式。我正在使用NSOperationQueue进行文件上传,我希望在队列中有东西时显示UIImageView。当队列中的每个操作完成时,我想删除UIImageView。
我认为这很容易做到,但过去一小时我一直被困住了。显示UIImageView非常简单,但我似乎无法删除它。这可能非常简单,我只是忽略了。这是我的代码。谢谢! :)
- (void)viewDidLoad {
//set up the uiimageview
self.spinnerView = [[UIImageView alloc] initWithFrame:CGRectMake([[UIScreen mainScreen] bounds].size.width-44,0,44,44)];
self.spinnerView.animationImages = [NSArray arrayWithObjects:
[UIImage imageNamed:@"0.gif"],
[UIImage imageNamed:@"1.gif"],
[UIImage imageNamed:@"2.gif"],
[UIImage imageNamed:@"3.gif"],
[UIImage imageNamed:@"4.gif"], nil];
self.spinnerView.animationDuration = 0.5f;
self.spinnerView.tag = 998;
self.spinnerView.animationRepeatCount = 0;
[self.view addSubview: self.spinnerView];
//set up the queue
self.uploadQueue = [[NSOperationQueue alloc] init];
[self.uploadQueue setMaxConcurrentOperationCount:1];
//set up observer for the queue
[self.uploadQueue addObserver:self forKeyPath:@"operationCount" options:NSKeyValueObservingOptionNew context:NULL];
}
- (void)newUpload:(NSData*)data {
[self.spinnerView startAnimating];
//....
//request is a NSURLRequest that's set up in this method
[NSURLConnection sendAsynchronousRequest:request queue:self.uploadQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
}];
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
change:(NSDictionary *)change context:(void *)context
{
if (object == self.uploadQueue && [keyPath isEqualToString:@"operationCount"]) {
if (self.uploadQueue.operationCount == 0) {
[self.spinnerView stopAnimating];
}
}
else {
[super observeValueForKeyPath:keyPath ofObject:object
change:change context:context];
}
我这样做是否正确?有没有更好的方法呢?我已经被困在这里一段时间了,我开始认为可能不是UIImageView搞砸了,而是我将NSURLRequests添加到NSOperationQueue的方式。
再次感谢!
答案 0 :(得分:2)
为什么不试试https://github.com/samvermette/SVProgressHUD或https://github.com/jdg/MBProgressHUD?它们完全是为了这个目的而制作的(在做一些异步工作时显示模态加载窗口)。它们易于使用,可以轻松自定义图像和许多其他选项。
答案 1 :(得分:0)
将此添加到您的.h文件中:UIImageView *spinnerView;
在您的.m文件中,您需要-(void)newUpload
中的类似内容:
if (code that says file uploads are done) {
spinnerView.hidden = YES;
}
答案 2 :(得分:0)
sendAsynchronousRequest:queue:completionHandler:
的文档说,只有在异步URL请求完成后,操作才会添加到指定的操作队列。此操作只是一个完成块。
所以我不认为你真正按照你想要的方式添加添加操作。 URL请求将在队列外部的自己的线程上运行,只有完成块放在队列中。如果你没有在完成块本身中指定任何内容,那么它甚至可能根本没有添加到队列中?
无论哪种方式,我都认为你没有向队列添加5个URL操作,然后用operationCount
== 5,4,3,2,1,0逐个执行。你是更多可能会触发5个同时发出的URL请求,并且在URL请求完成后,它们的完成块会以不确定的顺序添加到队列中。
要做我认为你打算做的事,你可以:
NSOperation
子类
管理NSURLConnection
和NSURLRequest
等AFNetworking
。 sendAsynchronousRequest:queue:completionHandler:
,但请使用。{
启动下一个请求的一个操作的完成处理程序,以及
停止微调器的最终请求的完成处理程序。
你可以在这里使用主队列作为唯一的工作
在队列中开始下一个操作或停止微调器。无论如何,URL请求的实际工作都是在它自己的线程上完成的。 编写自己的并发NSOperation有点棘手,我自己写了一篇,但我可能应该只使用AFNetworking。如果满足您的需求,选项3可能是最快的。