Iphone 带有UIActivityIndicator视图的活动指示器(微调器)
我有一个加载XML提要的tableView,如下所示:Iphone 带有UIActivityIndicator视图的活动指示器(微调器),iphone,objective-c,cocoa-touch,Iphone,Objective C,Cocoa Touch,我有一个加载XML提要的tableView,如下所示: - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if ([stories count] == 0) { NSString *path = @"http://myurl.com/file.xml"; [self parseXMLFileAtURL:path]; } } 我想让微调器在应用程序
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
if ([stories count] == 0) {
NSString *path = @"http://myurl.com/file.xml";
[self parseXMLFileAtURL:path];
}
}
我想让微调器在应用程序启动时显示在顶部栏上,并在数据显示在我的tableView上后消失
我认为将开头放在view上,将结尾放在-(void)parserdinddocument:(NSXMLParser*)parser上,但它不起作用
对于如何实现此解决方案,我非常感谢提供一个很好的解释性解决方案。我通常会实现一个NSTimer,它将调用我的微调器方法,我会在开始执行繁重的工作(通常会阻塞主线程的工作)之前立即启动该方法
NSTimer启动,并调用my spinner方法。当主要工作完成时,我禁用微调器
代码如下:
IBOutlet UIActiviyIndicatorView *loginIndicator;
{
...
[loginIndicator startAnimating];
[NSTimer scheduledTimerWithTimeInterval:0.1 target:self selector:@selector(executeAuthenticationRequest)
userInfo:nil repeats:NO];
...
}
- (void) executeAuthenticationRequest
{
/* Simulate doing a network call. */
sleep(3);
[loginIndicator stopAnimating];
...
}
您还可以执行以下操作:
IBOutlet NSProgressIndicator *pIndicator;
开始:
[pIndicator startAnimation:self];
[pIndicator setHidden:NO];
并停止:
[pIndicator stopAnimation:self];
[pIndicator setHidden:YES];
在Cocoa(和大多数其他应用程序框架)中,用户界面由主线程更新。操纵视图时,通常不会重新绘制视图,直到控件返回到运行循环并更新屏幕
因为您在主线程中解析XML,所以不允许屏幕更新,这就是为什么您的活动指示器没有出现的原因
您应该能够通过执行以下操作来修复它:
在ViewDidDisplay中,显示/设置微调器动画,然后调用
[自执行选择器:@selector(myXMLParsingMethod),对象:nil afterDelay:0]
在myXMLParsingMethod中,解析XML,然后隐藏/停止微调器
这样,控件将在解析开始之前返回到运行循环,以允许微调器开始设置动画。问题在于:NSXMLParser
是一个同步API。这意味着,只要在NSXMLParser
上调用parse
,该线程将完全无法解析xml,这意味着没有UI更新
我通常是这样解决这个问题的:
- (void) startThingsUp {
//put the spinner onto the screen
//start the spinner animating
NSString *path = @"http://myurl.com/file.xml";
[self performSelectorInBackground:@selector(parseXMLFileAtURL:) withObject:path];
}
- (void) parseXMLFileAtURL:(NSString *)path {
//do stuff
[xmlParser parse];
[self performSelectorOnMainThread:@selector(doneParsing) withObject:nil waitUntilDone:NO];
}
- (void) doneParsing {
//stop the spinner
//remove it from the screen
}
我已经多次使用这种方法,而且效果很好。如果你想做一些应该从主线程开始的事情,那么启动一个新线程可能会造成过度的杀伤力和复杂性
在我自己的代码中,我需要通过按下按钮启动MailComposer,但它可能需要一些时间才能出现,我希望确保UIActivityIndicator同时旋转
我就是这么做的:
-(无效)已单击提交:(id)事件
{
[自旋转启动];
[自执行选择器:@选择器(DisplayComposer Sheet),对象:nil afterDelay:0];
}
它将对工作表进行排队,而不是直接执行它。足以让微调器开始设置动画 如果您计划了一个计时器,然后阻塞了主线程,那么计时器将不会被触发。或者你是说你把阻塞工作放在timerdfire:method中了?sleep(3)调用就是我假装在做的工作。谢谢!这正是我需要的。