因此,当我在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”之间有几秒钟。然后指标终于显示出来了,所以我确信它会因为某种原因等到方法结束。有什么想法吗?
答案 0 :(得分:3)
您无法在同一功能中启动和停止活动指示器。
请参阅我为此问题提供的答案:How show activity-indicator when press button for upload next view or webview?
为清晰起见编辑:
- (void) someFunction
{
[activityIndicator startAnimation];
// do computations ....
[activityIndicator stopAnimation];
}
上述代码无效,因为当您在当前运行的函数中包含activityIndicator时,不会给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;
出于测试目的......