是否可以呈现UIAlertView并且不能继续执行该方法中的其余代码,直到用户响应警报?
提前致谢。
答案 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];
这是一个快速实现,所以随时找到任何错误;但是你明白了。