Предупреждение не отображается с помощью - - (void) alertView: clickedButtonAtIndex: метод - PullRequest
0 голосов
/ 22 июня 2011

Я занимаюсь разработкой этого приложения для iPhone, которое имеет базовые функции входа и выхода Требуется выполнить действие выхода из системы, как показано ниже.

  1. Сначала получите подтверждение пользователя с помощью UIAlertView
  2. Показать окно предупреждения о выходе из системы во время обработки выхода из системы на серверах

Логика сервера еще не реализована, но я столкнулся с проблемой при отображении этого второго окна предупреждения. Проблема в том, что окно предупреждения не отображается, и вместо этого основной поток просто переходит в спящий режим и переходит к контроллеру корневого представления. Может ли кто-нибудь помочь мне с этой проблемой.

Ниже приведен мой код:

Действие выхода из системы:

-(IBAction)logOut
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Really Want to Log Out?" 
                     message:@"If you continue you will be redirected to Home page, 
                     where you have to sign in again. \n\nContinue?" 
                     delegate:self cancelButtonTitle:@"Cancel" 
                     otherButtonTitles:@"Continue", nil];

[alert show];

[alert release];

}

Ввод пользователя (какую кнопку он нажал) будет обрабатываться следующим образом ...

-(void)alertView:(UIAlertView *) actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        [NSThread detachNewThreadSelector:@selector(dataProcessor) 
                  toTarget:self withObject:nil];
        [NSThread sleepForTimeInterval:3];
        [self.navigationController popToRootViewControllerAnimated:YES];
    } else {
        // do nothing
    }
}

И dataProcessor () реализован следующим образом:

-(void)dataProcessor { 

     NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; 

     UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Signing out...\n\nPlease Wait..." 
                           message:nil delegate:self cancelButtonTitle:nil 
                           otherButtonTitles: nil] autorelease];

     [alert show];

     UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] 
                initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

     indicator.center = CGPointMake(alert.bounds.size.width / 2, 
                                    alert.bounds.size.height - 50);
     [indicator startAnimating];
     [alert addSubview:indicator];
     [indicator release];


     [alert dismissWithClickedButtonIndex:0 animated:YES];

     [pool release]; 

}

Когда я использую этот подход, это предупреждение с UIActivityIndicator не отображается. Происходит следующее: контроллер приветствия отключается (я думаю, это из-за [NSThread sleepForTimeInterval: 3];) и возвращается к контроллеру корневого представления.

Также я попытался использовать тег с оповещениями, как упоминалось в этом сообщении Показать оповещение в clickedButtonAtIndex? Но все равно я не могу заставить это работать.

Пожалуйста, кто-нибудь может мне помочь? Заранее спасибо.

Ответы [ 2 ]

2 голосов
/ 22 июня 2011

Здесь довольно много вещей, которые не так.

  1. Работа с элементами UIKit в потоке, отличном от основного.
  2. Вы создаете оповещение, отображаете его и немедленно отклоняете. Конечно, в компьютерное время это должно произойти очень быстро. Так что ты даже не увидишь это.
  3. Блокировка пользовательского интерфейса. (Конечно, это то, что вы, кажется, хотите.)

Вы, вероятно, должны сделать это так,

-(void)alertView:(UIAlertView *) actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if (buttonIndex == 1) {
        [self dataProcessor];
    } else {
        // do nothing
    }
}

и позже в dataProcessor,

-(void)dataProcessor { 
     UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"Signing out...\n\nPlease Wait..." 
                           message:nil delegate:self cancelButtonTitle:nil 
                           otherButtonTitles: nil] autorelease];

     [alert show];

     UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] 
                initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];

     indicator.center = CGPointMake(alert.bounds.size.width / 2, 
                                    alert.bounds.size.height - 50);
     [indicator startAnimating];
     [alert addSubview:indicator];
     [indicator release];

     [self performSelector:@selector(dismissAndPop:) withObject:alert afterDelay:3.0f];
}

и объявить dismissAndPop: в .h и .m,

- (void)dismissAndPop:(UIAlertView *)alertView {
    [alertView dismissWithClickedButtonIndex:0 animated:NO];
    [alertView release];

    [self.navigationController popToRootViewControllerAnimated:YES];
}

Я только что обновил вашу логику, чтобы показать представление оповещения, и через 3 секунды запустите его отмену, после чего следует popViewControllerAnimated:.

0 голосов
/ 22 июня 2011

Вы должны никогда делать код, который действует на пользовательский интерфейс где-либо еще, кроме основного потока.

Каждый код, который изменяет что-либо в пользовательском интерфейсе, должен выполняться в пользовательском интерфейсе.

Кроме того, использование [NSThread sleepForTimeInterval] является методом блокировки, что является плохой практикой (активное ожидание против пассивного ожидания)

Если у вас не может быть метода делегата, который информирует вас о том, что обработка завершена, и вы все же хотите вместо этого подождать фиксированное количество секунд, используйте performSelector:withObject:afterDelay:, например, для вызова метода после заданной задержки; этот метод обычно, для вашего примера, отклоняет ваш alertView и вызывает метод popToRootViewControllerAnimated.

Другой вариант - использовать для этого NSTimer, но performSelector:withObject:afterDelay: должно быть намного проще в использовании.

...