iPhone活动指标被推迟了?

时间:2011-08-19 18:49:55

标签: iphone objective-c cocoa-touch uiactivityindicatorview

因此,当我在mapView中点击一个callout附件时,几秒钟内没有任何事情发生,因为它正在发出url请求并解析它,所以我想显示活动指示器,这样用户就不会认为它被冻结了。这是代码:

- (void)mapView:(MKMapView *)mv annotationView:(MKAnnotationView *)pin calloutAccessoryControlTapped:(UIControl *)control {
    // start activity indicator 
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    NSLog(@"tapped");

    ArtPiece *artPiece = (ArtPiece *)pin.annotation;

    //when annotation is tapped switches page to the art description page
    artDescription *artD = [[artDescription alloc] initWithNibName:@"artDescription" bundle:nil];
    artD.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
    artD.startingLocation = mapView.userLocation.location.coordinate;
    artD.selectedArtPiece = artPiece;
    NSLog(@"0");
    [self presentModalViewController:artD animated:YES];
    NSLog(@"1");

    [artD loadArt:artPiece];
    NSLog(@"2");
    // stop activity indicator 
    //[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

    [artD release];
}

奇怪的是(无论如何,也许我错过了一些显而易见的东西,因为我很缺乏经验),活动指示器直到方法完成后才会显示,并且模态视图开始动画进入视图。我把NSLogs放进去看看花了多少时间。我在“0”和“1”之间有大约2秒的暂停,在“1”和“2”之间有几秒钟。然后指标终于显示出来了,所以我确信它会因为某种原因等到方法结束。有什么想法吗?

3 个答案:

答案 0 :(得分:3)

您无法在同一功能中启动和停止活动指示器。

请参阅我为此问题提供的答案:How show activity-indicator when press button for upload next view or webview?

为清晰起见编辑:

- (void) someFunction
{
    [activityIndicator startAnimation];

    // do computations ....

    [activityIndicator stopAnimation];  
}

上述代码无效,因为当您在当前运行的函数中包含activityIndi​​cator时,不会给UI时间更新。所以我和其他许多人所做的就是把它分成一个单独的线程,如下所示:

- (void) yourMainFunction {
    activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

    [NSThread detachNewThreadSelector:@selector(threadStartAnimating) toTarget:self withObject:nil];

    //Your computations

    [activityIndicator stopAnimating];

}

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

答案 1 :(得分:3)

在控件返回到应用程序的main run loop之前,对UI的更改(显示活动指示符)不会生效。直到您的方法结束并且堆栈已展开后才会发生这种情况。您需要显示活动指示符,然后将您正在等待的活动转储到后台线程:

[self performSelectorInBackground:@selector(doThingINeedToWaitFor:)
                       withObject:anObject];

(请注意,您recommends; move away from using threads explicitly的Apple performSelectorInBackground:withObject:是使主线程运行一些代码的最简单方法。更复杂的选项可用于其他情况。请参阅Concurrency Programming Guide。)

重要的问题是仍然需要在主线程上处理UI更新,因此在该方法中,当工作完成时,您需要回调以停止活动指示符:

- (void) doThingINeedToWaitFor: (id)anObject {
    // Creating an autorelease pool should be the first thing
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];

    // Do your work...
    // ...
    // Update the UI back on the main thread
    [self performSelectorOnMainThread:@selector(allDoneWaiting:)
                           withObject:nil
                        waitUntilDone:YES];
    // Clear out the pool as the final action on the thread
    [pool drain];
}

在您的回调方法中,您再次隐藏活动指示器并执行必要的任何其他后处理。

答案 2 :(得分:0)

某些东西正在减慢你的旋转器。我建议你在背景中使用线程进行繁重的工作。试试这个:

-(void)myMethod{
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    [NSThread detachNewThreadSelector:@selector(startWorkingThread) toTarget:self withObject:nil];
}

-(void)startWorkingThread{
     //Heavy lifting
     [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}

我认为您已评论过:

[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

出于测试目的......