这是我的代码...

- (void) threadStartAnimating {
    [activityIndicator startAnimating];
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    activityIndicator=[[UIActivityIndicatorView alloc] init];
    [activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
    activityIndicator.center=[self tableView].center;
    [[self tableView] addSubview:activityIndicator];

    [NSThread detachNewThreadSelector:@selector(threadStartAnimating) toTarget:self withObject:nil];
    EventController *eventController = [[EventController alloc] init];
    [eventController setEventID:[[lineItems objectAtIndex:[indexPath row]] objectForKey:@"view_event_button_param"]];
    [activityIndicator stopAnimating];
    [[self navigationController] pushViewController:eventController animated:YES];
}


事件控制器包含一个Web服务,需要花费几秒钟来加载。我可以显示活动指示器的唯一方法是在其中抛​​出无限循环...我发现了一堆示例,其中提到将其放在单独的线程中,但似乎不起作用。

最佳答案

您的问题是,如果要在viewDidLoad中获取数据,则只有在加载视图之后才调用该方法,通常是在首次显示该视图控制器的过程中。您的情况是在pushViewController:animated:调用期间。

因此,一种执行所需操作的方法可能是围绕以下两行进行交换:

[activityIndicator stopAnimating];
[[self navigationController] pushViewController:eventController animated:YES];


但是,老实说,我会创建一个名为EventControllerDelegate的协议,在您的id <EventControllerDelegate>中具有对EventController的弱引用属性,然后设置视图控制器,该视图控制器会在将其推送之前将EventController创建为委托。然后在委托中定义一个方法,并在视图控制器中实现它,然后在该方法中停止微调器。然后,在EventController中,当您完成数据加载后,调用委托方法。

编辑:如果您确实想在不定义委托的情况下进行操作,则可以尝试将代码更改为以下内容:

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    activityIndicator=[[UIActivityIndicatorView alloc] init];
    [activityIndicator setActivityIndicatorViewStyle:UIActivityIndicatorViewStyleWhiteLarge];
    activityIndicator.center=[self tableView].center;
    [[self tableView] addSubview:activityIndicator];

    EventController *eventController = [[EventController alloc] init];
    [eventController setEventID:[[lineItems objectAtIndex:[indexPath row]] objectForKey:@"view_event_button_param"]];

    [activityIndicator startAnimating];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        UIView *v = eventController.view;

        dispatch_async(dispatch_get_main_queue(), ^{
            [activityIndicator stopAnimating];
            [[self navigationController] pushViewController:eventController animated:YES];
        });
    });
}


为了清楚起见,它使用GCD和通常的“访问view属性以强制loadView / viewDidLoad” hack。

07-25 23:03