Search code examples
iphoneiosibactionalertview

iOS- How to show alertView before code starts


I have the following code:

-(IBAction)showAlertView:(id)sender{

alertView = [[UIAlertView alloc] initWithTitle:@"Atualizando" message:@"\n"delegate:self cancelButtonTitle:nil otherButtonTitles:nil];

spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];   
spinner.center = CGPointMake(139.5, 75.5); // .5 so it doesn't blur
[alertView addSubview:spinner];
[spinner startAnimating];
[alertView show]; 
}


-(IBAction)getContacts:(id)sender {

[self showAlertView:(id)self];

ABAddressBookRef addressBook = ABAddressBookCreate( );
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );

I want to show the alert before the rest of the IBAction begins, but im seeing the alertView only at the end of the IBAction. What am I doing wrong?

EDIT: i have:

-(IBAction)getContacts:(id)sender {

// display the alert view
[self showAlertView:self];

// do the synchronous operation on a different queue
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

ABAddressBookRef addressBook = ABAddressBookCreate( );
CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );

....

if ([contact length] == 8) {

            NSString *first = (NSString*)ABRecordCopyValue(person, kABPersonFirstNameProperty);
            NSString *last = (NSString*)ABRecordCopyValue(person, kABPersonLastNameProperty);
            NSString *phone = contact;
            ContactInfo *user1 = [[ContactInfo alloc] init];
            user1.first = first;
            user1.last = last;
            user1.phone = phone;
            user1.person = person;
            user1.phoneIdx = j;
            user1.book = addressBook;
            NSLog(@"phone is %@", phone);
            [secondViewController.users addObject:user1];
        }
        ABRecordSetValue(person, kABPersonPhoneProperty, mutablePhones, &error);
    }
}
bool didSave = ABAddressBookSave(addressBook, &error);
if(!didSave){
    NSLog(@"error!");
}
dispatch_async(dispatch_get_main_queue(), ^{
    [self hideAlertView]; // or however you want to do it
});

UIAlertView *alertAlmost = [[UIAlertView alloc] initWithTitle:@"Quase Pronto" message:@"Os seguintes contatos não tem código de área. Porfavor, selecione os contatos que você deseja adicionar o digito 9 e pressione Ok (caso não queira adicionar em nenhum, pressione Ok) " delegate:self cancelButtonTitle:@"Ok!" otherButtonTitles:nil];
[alertAlmost show];

[self presentViewController: secondViewController animated:YES completion: NULL];
 });
}

I want the alert to dismiss, and then i can call the table view. Any sugestions?


Solution

  • Showing a UIAlertView is done asynchronously, so if you call showAlertView: at the top of the method, it'll show the alert view and then return immediately after, then do the rest of your method.

    If you want the rest of your method to happen after the alert view is dismissed, you need to add yourself as the alert view's delegate, then implement the method

    - (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex
    

    and do the rest of your stuff in there.


    Edit: Okay, I think I get your problem. You're doing some time consuming synchronous operation on the main queue and that's blocking it so that the alert view isn't displayed until later.

    You should move the time consuming operation to a different queue like so:

    -(IBAction)getContacts:(id)sender {
        // display the alert view
        [self showAlertView:self];
    
        // do the synchronous operation on a different queue
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            ABAddressBookRef addressBook = ABAddressBookCreate( );
            CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
            CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );
    
            // once this operation has finished, you can hide the alert view like so:
            dispatch_async(dispatch_get_main_queue(), ^{
                [self hideAlertView]; // or however you want to do it
            });
        });
    }