带有UIActivityIndi​​catorView的活动指示器(微调器)

时间:2010-02-14 20:59:39

标签: iphone objective-c cocoa-touch

我有一个tableView,它按如下方式加载XML Feed:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];

    if ([stories count] == 0) {
        NSString *path = @"http://myurl.com/file.xml";
        [self parseXMLFileAtURL:path];
    }
}

我想让微调器在应用程序启动时显示在顶栏上,并在数据显示在我的tableView上后显示消息。

我认为将开头放在viewDidAppear并将结尾放在-(void)parserDidEndDocument:(NSXMLParser *)parser但是它不起作用。

我很欣赏有关如何实施此解决方案的解决方案。

4 个答案:

答案 0 :(得分:5)

问题在于:NSXMLParser是一个同步API。这意味着只要在parse上调用NSXMLParser,该线程就会完全解析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
}

我多次使用过这种方法,效果很好。

答案 1 :(得分:3)

如果你想做一些应该在主线程上开始的事情,开始一个新线程可能会过度使用并且是一个复杂的来源。

在我自己的代码中,我需要通过按下按钮来启动MailComposer,但它可能需要一些时间才能出现,我想确保UIActivityIndi​​cator同时旋转。

这就是我的所作所为:

- (无效)submit_Clicked:(ID)事件 {     [self.spinner startAnimating];     [self performSelector:@selector(displayComposerSheet)withObject:nil afterDelay:0]; }

它将对displayComposerSheet进行排队,而不是立即执行它。足够让微调器开始制作动画!

答案 2 :(得分:2)

我通常会实现一个NSTimer,它将调用我的spinner方法,我在进行繁重的工作之前就开始了(通常会阻塞主线程的工作)。

NSTimer触发并调用我的微调器方法。主要工作完成后,我禁用微调器。

代码就像:

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];

答案 3 :(得分:1)

在Cocoa(和大多数其他应用程序框架)中,用户界面由主线程更新。操作视图时,通常不会重新绘制视图,直到控件返回到运行循环并更新屏幕。

因为您正在解析主线程中的XML,所以您不允许更新屏幕,这就是您的活动指示器没有出现的原因。

您应该可以通过执行以下操作来解决此问题:

  1. 在viewDidAppear中,显示/动画微调器,然后调用

    [self performSelector:@selector(myXMLParsingMethod)withObject:nil afterDelay:0];

  2. 在myXMLParsingMethod中,解析XML,然后隐藏/停止微调器。

  3. 这样,控件将在解析开始之前返回到运行循环,以允许微调器开始动画。