iphone UIAlertView Modal

时间:2010-11-22 17:26:06

标签: iphone objective-c modal-dialog uialertview

是否可以呈现UIAlertView并且不能继续执行该方法中的其余代码,直到用户响应警报?

提前致谢。

5 个答案:

答案 0 :(得分:20)

我想停止你想要的代码是停止设备运行你在alertview之后编写的下一个代码

为此,只需在alertview之后删除您的代码,并将该代码放入alertview委托

-(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 
    }
}

不要忘记在.h文件中包含UIAlertViewDelegate

答案 1 :(得分:9)

答案已被接受,但我会注意到遇到此问题的任何人,虽然您不应该将此用于正常的警报处理,但在某些情况下您可能希望阻止当前的执行路径继续正在提出警报。为此,您可以在主线程的运行循环中旋转。

我使用这种方法来处理我想在崩溃之前呈现给用户的致命错误。在这种情况下,发生了灾难性的事情,所以我不想从导致错误的方法返回,这可能允许其他代码以无效状态执行,例如,数据损坏。

请注意,这不会阻止事件被处理或阻止其他线程运行,但由于我们正在呈现一个基本上接管接口的警报,因此事件通常应限于该警报。

// 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
}

答案 2 :(得分:1)

不,但简单的解决方法是在您呈现UIAlertView的位置拆分代码 - 并在解除警报时从您的委托方法开始第二部分。

答案 3 :(得分:1)

我刚刚遇到了MonoTouch的这个问题,试图找到之前的答案遇到了这个悬而未决的问题。

是的,有可能。 C#中的以下示例展示了如何使用MonoTouch执行此操作,Objective-C版本应该很容易编写:

要做到这一点,你可以做的是手动运行mainloop。我没有设法直接停止主循环,所以我改为运行主循环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;
}

答案 4 :(得分:1)

如果需要等待的代码全部采用相同的方法(或者可以),则可以使用其他选项。我已经创建了一个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];

这是一个快速实现,所以随时找到任何错误;但是你明白了。