iphone UIAlertView Модальный - PullRequest
       17

iphone UIAlertView Модальный

10 голосов
/ 22 ноября 2010

Можно ли представить UIAlertView и не продолжать выполнение остальной части кода в этом методе, пока пользователь не ответит на предупреждение?

Заранее спасибо.

Ответы [ 5 ]

20 голосов
/ 22 ноября 2010

Я думаю, что остановка кода, который вы имели в виду, состояла в том, чтобы остановить устройство для запуска следующего кода, который вы написали после просмотра предупреждений

Для этого просто удалите код после просмотра предупреждений и поместите этот код в делегат просмотра предупреждений

-(void) yourFunction
{
     //Some code
     UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"" message:@"Your Message" delegate:self cancelButtonTitle:nil otherButtonTitles:@"OK", nil];
            [alert show];
            [alert release];
     //Remove all your code from here put it in the delegate of alertview
}
-(void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:    (NSInteger)buttonIndex 
{
if(buttonIndex==0)
    {
        //Code that will run after you press ok button 
    }
}

Не забудьте включить UIAlertViewDelegate в файл .h

9 голосов
/ 28 июня 2012

Ответ уже принят, но я отмечу для всех, кто сталкивался с этим вопросом, что, хотя вы не должны использовать его для обычной обработки оповещений, в некоторых случаях вы можете помешать продолжению текущего пути выполненияво время представления предупреждения.Для этого вы можете запустить цикл выполнения для основного потока.

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

Обратите внимание, что это не помешает обработке событий и не заблокирует запуск других потоков, но, поскольку мы представляем предупреждение, которое по существу перехватывает интерфейс, события обычно должны быть ограничены этим предупреждением.

// Present a message to the user and crash
-(void)crashNicely {

  // create an alert
  UIAlertView *alert = ...;

  // become the alert delegate
  alert.delegate = self;

  // display your alert first
  [alert show];

  // spin in the run loop forever, your alert delegate will still be invoked
  while(TRUE) [[NSRunLoop currentRunLoop] runUntilDate:[NSDate distantFuture]];

  // this line will never be reached
  NSLog(@"Don't run me, and don't return.");

}

// Alert view delegate
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
  abort(); // crash here
}
1 голос
/ 28 января 2014

Если код, который должен ждать, все в одном и том же методе (или может быть), блоки могут быть другой опцией.Я создал подкласс UIAlertView, чтобы справиться с этим.Просто имейте в виду, что выполнение все равно будет продолжаться после вызова [alert show];это просто дает вам возможность передавать переменные стека без создания новых промежуточных переменных класса.Кроме того, если вы еще не знакомы с блоками Objective-C, вам следует прочитать документацию по нему;Есть несколько ошибок и некоторый странный синтаксис, которые вы должны знать.

Идет примерно так:

typedef void (^MyAlertResult)(NSInteger clickedButtonIndex);

@interface MyBlockAlert : UIAlertView
{
    MyAlertResult finishedBlock;
}
- (void) showWithCompletionBlock:(MyAlertResult)block;
...

- (void) showWithCompletionBlock:(MyAlertResult)block
{
    self.delegate = self;
    finishedBlock = [block copy];
    [self show];
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    finishedBlock(buttonIndex);
    [finishedBlock release];
    finishedBlock = nil;
}

используется так:

__block NSArray* arrayOfDeletes; // set to something
MyBlockAlert* areYouSureAlert = [[MyBlockAlert alloc] initWithTitle:@"Really delete?" message:@"Message" delegate:nil cancelButtonTitle:@"Cancel" otherButtonTitles:@"Delete", nil];

[arrayOfDeletes retain]; // Make sure retain count is +1

[areYouSureAlert showWithCompletionBlock:
^(NSInteger clickedButtonIndex)
{
    if (clickedButtonIndex == 1)
    {
        // Clicked okay, perform delete
    }
    [arrayOfDeletes release];
}];
[areYouSureAlert release];

Это былобыстрая реализация, поэтому не стесняйтесь находить любые ошибки;но вы поняли.

1 голос
/ 26 января 2011

Я только что натолкнулся на этот вопрос для MonoTouch, и попытка найти предыдущий ответ натолкнулась на этот открытый вопрос.

Да, это возможно.В следующем примере на C # показано, как вы можете сделать это с MonoTouch, эту версию Objective-C легко написать:

Чтобы сделать это, вы можете запустить основной цикл вручную.Мне не удалось остановить основной цикл напрямую, поэтому я вместо этого запускаю основной цикл в течение 0,5 секунды и жду, пока пользователь ответит.

Следующая функция показывает, как можно реализовать модальный запрос с помощью вышеуказанного подхода:

int WaitForClick ()
{
    int clicked = -1;
    var x = new UIAlertView ("Title", "Message",  null, "Cancel", "OK", "Perhaps");
    x.Show ();
    bool done = false;
    x.Clicked += (sender, buttonArgs) => {
        Console.WriteLine ("User clicked on {0}", buttonArgs.ButtonIndex);
    clicked = buttonArgs.ButtonIndex;
    };    
    while (clicked == -1){
        NSRunLoop.Current.RunUntil (NSDate.FromTimeIntervalSinceNow (0.5));
        Console.WriteLine ("Waiting for another 0.5 seconds");
    }

    Console.WriteLine ("The user clicked {0}", clicked);
    return clicked;
}
1 голос
/ 22 ноября 2010

Нет, но самое простое решение - разделить ваш код в том месте, где вы представляете UIAlertView, - и запустить вторую часть из метода делегата, когда предупреждение отклонено.

...