0
votes

I'm using two threads in an iPhone app for the first time and I've run into a problem. In this prototype, I have a view controller that loads a local web page. I want an activity indicator to show until the page has finished loading. With the code below, the activity indicator starts, the page loads properly, but the activity indicator does not stop or hide. It doesn't look like the "loading" function ever gets called.

What am I doing wrong?

- (void)viewDidLoad {
 [self.view addSubview:activityIndicator];
 [activityIndicator startAnimating];
 [NSThread detachNewThreadSelector:@selector(getData) toTarget:self withObject:nil];
 [super viewDidLoad];
}
- (void)getData {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 [detailWebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"page1" ofType:@"html"]isDirectory:NO]]];
 [NSTimer scheduledTimerWithTimeInterval: (1.0/2.0) target:self selector:@selector(loading) userInfo:nil repeats:YES];
 [pool release];
}
- (void)loading {
 if(!detailWebView.loading){
 [activityIndicator stopAnimating];
 [activityIndicator removeFromSuperview];
 }
4
I appreciate from some of the answers that threading doesn't appear to be necessary for this, but I'm trying to figure out how to use threading for a more complex scenario that I'm about to tackle. This is just a prototype. - Phil John

4 Answers

2
votes

There's an easier way to do this without creating your own thread.

- (void)viewDidLoad {
    [self.view addSubview:activityIndicator];
    [activityIndicator startAnimating];
    [detailWebView setDelegate:self];
    [detailWebView loadRequest:[NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"page1" ofType:@"html"]isDirectory:NO]]];
    [super viewDidLoad];
}

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [activityIndicator stopAnimating];
}
1
votes

You 'd betetr stop the activity indicator in the webview delegate method :

-(void)webViewDidFinishLoad:(UIWebView*)webView
0
votes

Have you added debug output to loading to whether it gets called ? The code sure looks like that, it should get called after 0.5 seconds and I'd guess that detailWebView is still loading then.

Also, GUI stuff should be run on the main thread, so you may need to do:

- (void)loading {
  if(!detailWebView.loading){
    [activityIndicator performSelectorOnMainThread:@selector(stopAnimating) withObject:nil waitUntilDone:YES];
    [activityIndicator performSelectorOnMainThread:@selector(removeFromSuperView) withObject:nil waitUntilDone:YES];
  }
}
0
votes

You're using a webview, which already provides a mechanism to know when a load has finished, and already loads data asynchronously - the use of a custom thread really isn't needed.

Register your object as the UIWebView's delegate. Call loadRequest on the UIWebView and start animating the progress indicator. Stop animating the progress indicator in:

-(void)webViewDidFinishLoad:(UIWebView*)webView

This method is defined by the UIWebViewDelegate protocol - make sure your object implements this protocol. You implement this method:

- (void)webViewDidFinishLoad:(UIWebView *)webView {
    [activityIndicator stopAnimating];
}

http://developer.apple.com/iphone/library/documentation/uikit/reference/UIWebViewDelegate_Protocol/Reference/Reference.html