2010-11-22 48 views
10

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

在此先感谢。

+2

不会停止代码意味着它将无法响应用户按下按钮? – 2010-11-22 17:29:33

回答

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

不要忘记,包括UIAlertViewDelegate在.h文件

+4

呃。有点难过,这是解决这个问题的最好方法。 “糟糕,我刚刚意识到我应该确保用户在执行代码之前想要这样做,现在让我重新组织我的所有代码......” – GeneralMike 2012-10-25 18:10:39

+0

悲伤,但更加异步。 – devios1 2013-03-25 21:43:22

+0

如果我有'yourFunction'的参数会怎么样?我怎样才能把它交给代表? – turzifer 2013-12-17 14:40:41

1

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

1

我只是碰到了这个问题来到了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; 
} 
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 
} 
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]; 

这是一个快速的实现,可以随意发现任何错误;但你明白了。