Search code examples
iphoneuiviewuisearchbarbusyindicator

iPhone Busy View


I am trying to get a busy view displayed during a search process however it never seems to display.

What I am trying to achieve

  1. User clicks on search button once they have entered the text in a UISearchBar.
  2. The text entered is delegated to searchBarSearchButtonClicked.
  3. Show a "Busy view" which is a UIView containing a UIActivityIndicatorView to indicate the search is underway.
  4. Perform a search which communicates with a website.
  5. On search completion remove the "Busy View".

Whats wrong

The search process is working fine, using the debugger I can see it moving through the searchBarSearchButtonClicked function fine however the "Busy View" never appears. The search takes 2-3 seconds so in theory I should see my "Busy View" appear for those 2-3 seconds.


Code Attempt 1 - Add and remove the "Busy View" from the superview**

- (void)searchBarSearchButtonClicked:(UISearchBar *)activeSearchBar {

 [activeSearchBar setShowsCancelButton:NO animated:YES];
 [activeSearchBar resignFirstResponder];
 [busyView activateSpinner]; //start the spinner spinning
 [self.view addSubview:busyView]; //show the BusyView

 Search *search = [[Search alloc]init];
 results = [search doSearch:activeSearchBar.text];

 [busyView deactivateSpinner]; //Stop the spinner spinning
 [busyView removeFromSuperview]; //remove the BusyView
 [search release]; search = nil;

}

Results Of Attempt 1 - It does not appear, however if I comment out the removeFromSuperview call the Busy View remains on screen.


Code Attempt 2 - using animations

- (void)searchBarSearchButtonClicked:(UISearchBar *)activeSearchBar {



[activeSearchBar setShowsCancelButton:NO animated:YES]; 
 [activeSearchBar resignFirstResponder];

 [UIView beginAnimations:nil context:nil];
 [UIView setAnimationDuration:0];
 [UIView setAnimationDelegate:self];
 [UIView setAnimationDidStopSelector:@selector(animationDidStop)];

 [busyView activateSpinner]; //start spinning the spinner
 [self.view addSubview:busyView]; //show the busy view

 [UIView commitAnimations];

 Search *search = [[Search alloc]init];
 results = [search doSearch:activeSearchBar.text];


 [UIView beginAnimations:nil context:nil];
 [UIView setAnimationDuration:0];
 [UIView setAnimationDelegate:self];
 [UIView setAnimationDidStopSelector:@selector(animationDidStop)];

 [busyView deactivateSpinner]; //sets stops the spinner spinning
 [busyView removeFromSuperview]; //remove the view

 [UIView commitAnimations];
 [search release]; search = nil;
}

Results of attempt 2 - Did not see the "Busy View" appear


Solution

  • Well, Here's my solution:

    • Create singleton class MyLoadingView. This class should contain show and hide static methods.
    • In MyLoadingView constructor you should manually create a view with semi-transparent black background and activityview inside of it. Place this view into [[UIApplication sharedApplication] keyWindow]. Hide it.
    • [MyLoadingView show] invocation just brings myLoadingView object to front in it's container: [[[UIApplication sharedApplication] keyWindow] bringSubviewToFront:myLoadingViewSharedInstance];. Also don't forget to start activityview animation.
    • [MyLoadingView hide] stops activityview animation and hides sharedInstanceView.

    Please notice, that you need to invoke [MyLoadingView show] in a separate thread.