Search code examples
iosxcodeibactioniboutletindicator

How to change instantly a button to an activity indicator in xcode 6


I'm trying to change a button in the navigation bar to an activity indicator instantly when it was pressed. I tryed this code, but the button change only when the IBaction process end:

- (BOOL)connected {
Reachability *reachability = [Reachability reachabilityForInternetConnection];
NetworkStatus networkStatus = [reachability currentReachabilityStatus];
return networkStatus != NotReachable;
}

- (IBAction)scaricaDatabase:(id)sender {
if (![self connected]) {
    _navTitle.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Non connesso" style:UIBarButtonItemStylePlain target:nil action:nil];
} else {
    UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
    UIBarButtonItem * barButton = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
    activityIndicator.color = [UIColor blackColor];

    // Set to Left or Right
    [activityIndicator startAnimating];
    [[self navTitle] setLeftBarButtonItem:barButton];

    NSString *dropboxHttpsUrl = @"https://dl.dropboxusercontent.com/u/68843065/eventiMedievale.sql";
    NSData *dbFile = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:dropboxHttpsUrl]];

    if(dbFile) {
        NSLog(@"%lu", (unsigned long)[dbFile length]);
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *appFile = [documentsDirectory stringByAppendingPathComponent:@"eventiMedievaleUpd.sql"];
        [dbFile writeToFile:appFile atomically:YES];
        NSLog(@"%@", appFile);
        _navTitle.leftBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:@"Aggiornato" style:UIBarButtonItemStylePlain target:nil action:nil];
    }else{
        NSLog(@"File non scaricato");
    }
}

I need to show the activity indicator when the process is downloading the sql file, but for now I only get the update of the navigation bar at the end of this process.

Could someone help me?

Thanks :)


Solution

  • I would try placing the NSData download portion into a background thread using Grand Central Dispatch. This should go within your IBAction

    UIActivityIndicatorView *activityIndicator = [[UIActivityIndicatorView alloc] initWithFrame:CGRectMake(0, 0, 20, 20)];
    UIBarButtonItem * barButton = [[UIBarButtonItem alloc] initWithCustomView:activityIndicator];
    activityIndicator.color = [UIColor blackColor];
    
    // Set to Left or Right
    [activityIndicator startAnimating];
    [[self navTitle] setLeftBarButtonItem:barButton];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ // 1
            //load the data here
            dispatch_async(dispatch_get_main_queue(), ^(void) {
                //remove the activity indicator 
            });
        });