Question

I have an app with a table view controller in which a user selects a US state, a web service is called and data is displayed for that state in the destination table view controller. Since the web service can take some time to complete I want an activity indicator. Since there will be no temporary data to display, I need this to be processed synchronously. So my task is pretty simple: start the activity indicator, call the web service, and after it completes, stop the activity indicator.

I am obviously doing something wrong and no activity indicator ever displays.

Here is the code from my destination table view controller's viewDidAppear method:

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    [self.tableView bringSubviewToFront:spinner];
    spinner.hidesWhenStopped = YES;
    spinner.hidden = NO;
    [spinner startAnimating];
    stateGauges = [[GaugeList alloc] initWithStateIdentifier:stateIdentifier andType:nil];
    [self.tableView reloadData];
    [spinner stopAnimating];
}

Header:

@property (strong, nonatomic) UIActivityIndicatorView *spinner;

GaugeList is the object which makes the web service call.

Can someone tell me how to get an activity indicator view to appear? Thanks!

Was it helpful?

Solution

You forgot to add spinner on table view. Your code should look as follows:

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    spiner.center = //set some center
    [self.tableView addSubview: spinner];
    [self.tableView bringSubviewToFront:spinner];
    spinner.hidesWhenStopped = YES;
    spinner.hidden = NO;
    [spinner startAnimating];
    stateGauges = [[GaugeList alloc] initWithStateIdentifier:stateIdentifier andType:nil];
    [self.tableView reloadData];
    [spinner stopAnimating];
}

Also you send requests to a web service in main thread. This is bad practice. I would suggest something like following:

-(void)viewDidAppear:(BOOL)animated{
    [super viewDidAppear:animated];
    spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
    spiner.center = //set some center
    [self.tableView addSubview: spinner];
    [self.tableView bringSubviewToFront:spinner];
    spinner.hidesWhenStopped = YES;
    spinner.hidden = NO;
    [spinner startAnimating];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
        stateGauges = [[GaugeList alloc] initWithStateIdentifier:stateIdentifier andType:nil];
        dispatch_async(dispatch_get_main_queue(), ^{
            [self.tableView reloadData];
            [spinner stopAnimating];
        });
    });
}

OTHER TIPS

At first you should add activity indicator to some view to show it. But you can not add it to UITableView, because UITableView is subclass of UIScrollView and you will see floating activity indicator. The best way in your case is to add activity indicator to navigation bar, etc. Or if you want to disable table view you should write something like this:

- (void)viewDidLoad {
    [super viewDidLoad];
    UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
    UIView *dummyView = [[UIView alloc] init];
    dummyView.frame = self.tableView.bounds;
    dummyView.alpha = 0.5f;
    dummyView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
    dummyView.userInteractionEnabled = YES;
    dummyView.backgroundColor = [UIColor blackColor];
    [dummyView addSubview:activityIndicator];
    activityIndicator.center = dummyView.center;
    [self.tableView addSubview:dummyView];
}

Try using self.spinner instead of using spinner.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top