我正在制作一个应用程序,该应用程序显示动画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搞砸了,而是我将NSURLRequest添加到NSOperationQueue的方式。
再次感谢!
为什么不试试https://github.com/samvermette/SVProgressHUD或https://github.com/jdg/MBProgressHUD?它们正是为了这个目的而制作的(在做一些异步工作时显示模式加载窗口)。它们既易于使用,又易于为您的图像和许多其他选项进行自定义。
sendAsynchronousRequest:queue:completionHandler:
的文档说,只有在异步URL请求完成后,操作才会添加到指定的操作队列中。这个操作只是一个完成块。
因此,我不认为您真的在以您想要的方式向队列添加添加操作。URL请求将在队列外的自己的线程上运行,只有完成块被放入队列中。如果您在完成块本身中没有指定任何内容,那么它可能根本没有添加到队列中?
无论哪种方式,我都不认为您要向队列添加5个URL操作,然后这些操作以operationCount
==5,4,3,2,1,0一个接一个地执行。您更有可能同时触发5个URL请求,在它们的URL请求完成后,它们的完成块以不确定的顺序添加到队列中。
要做我认为你打算做的事情,你可以:
- 编写一个包含和的"并发"
NSOperation
子类管理CCD_ 4和CCD_ - 使用
AFNetworking
- 继续使用
sendAsynchronousRequest:queue:completionHandler:
,但使用启动下一个请求的一个操作的完成处理程序,以及停止微调器的最终请求的完成处理程序。您可以使用这里的主队列作为唯一正在完成的工作队列中正在启动下一个操作或停止微调器。URL请求的实际工作无论如何都是在它自己的线程上完成的
编写自己的并发NSOperation有点棘手,我自己写了一个,但我可能应该只使用AFNetworking。如果选项3能满足您的需求,那么它可能是最快的。
将其添加到.h文件中:UIImageView *spinnerView;
在.m文件中,您可能希望-(void)newUpload
:中包含类似的内容
if (code that says file uploads are done) {
spinnerView.hidden = YES;
}