2

私は次のコードを持っています:

-(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 );

残りのIBActionが始まる前にアラートを表示したいのですが、IBActionの最後にのみalertViewが表示されます。私は何が間違っているのですか?

編集:私は持っています:

-(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];
 });
}

アラートを閉じて、テーブルビューを呼び出すことができます。何か疑惑はありますか?

4

3 に答える 3

5

aの表示UIAlertViewは非同期で行われるためshowAlertView:、メソッドの先頭で呼び出すと、アラートビューが表示され、直後に戻ってから、メソッドの残りの部分を実行します。

アラートビューが閉じられた後にメソッドの残りの部分を実行する場合は、アラートビューとして自分自身を追加してからdelegate、メソッドを実装する必要があります。

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

残りの作業はそこで行います。


編集:さて、私はあなたの問題を抱えていると思います。メインキューで時間のかかる同期操作を実行しているため、メインキューがブロックされているため、アラートビューは後で表示されます。

時間のかかる操作を次のように別のキューに移動する必要があります。

-(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
        });
    });
}
于 2012-07-19T02:02:48.000 に答える
0

getContacts:アラートが閉じられたら、「」の残りのコードを実行する必要があります。UIAlertViewに「self」(アラートを表示するビューコントローラー)のデリゲートを設定し、ユーザーがボタンをクリックしてアラートを閉じるときに「addressBook」を実行します。

たとえば、UIAlertViewDelegateメソッドalertView:clickedButtonAtIndex:を実装し、そこでアドレス帳の処理を行います(ドキュメントをリンクしました)。

于 2012-07-19T02:01:49.897 に答える
0

進行状況インジケーターなどのアラートをポップアップし、そのアラートが表示されている間に、他のプロセスを開始したいと言っていると思います。現在、アラートをすぐに表示するように要求していますが、他の回答が述べているように、その呼び出しは非同期であり、UIスレッドは、他の作業を開始する前にアラートを表示することができません。

あなたはこれを試すことができます:

-(IBAction)getContacts:(id)sender {

    [self showAlertView:(id)self];
    [self performSelectorInBackground: @selector(initAddressBook) withObject: nil];
}

-(void)initAddressBook {
    ABAddressBookRef addressBook = ABAddressBookCreate( );
    CFArrayRef allPeople = ABAddressBookCopyArrayOfAllPeople( addressBook );
    CFIndex nPeople = ABAddressBookGetPersonCount( addressBook );
}

アドレス帳の作業をバックグラウンドで実行することに問題がある場合は、UIスレッドに次のようなアラートを投稿するのに十分な時間を与えることもできます。

-(IBAction)getContacts:(id)sender {

    [self showAlertView:(id)self];
    [self performSelector: @selector(initAddressBook) withObject: nil afterDelay: 0.1f];
}
于 2012-07-19T02:20:33.383 に答える