使UIAlertView阻塞

我需要使UIAlertView阻止。 因为我有function,我需要返回UIAlertViewselect。 但问题是,显示UIAlertView后,我的function代码进一步执行,所以我不能捕获UIAlertViewselect(我可以在委托方法,但我需要返回函数结果)。

我试图用NSCondition使UIAlertVIew阻塞。 但代码不起作用。

 condition = [NSCondition new]; result = 0 ; [condition lock]; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Fingerprint" message:@"test" delegate:window_self cancelButtonTitle:@"No" otherButtonTitles:@"Yes",nil]; [alert setDelegate:self]; [alert show]; while (result == 0) [condition wait]; [condition unlock] ; - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { [condition lock] ; if (buttonIndex == 0) { result = 2; } else if (buttonIndex == 1) { result = 3 ; } [condition signal] ; [condition unlock] ; } 

也许如何解决这个代码或其他build议? 谢谢

没有办法达到你想要的。 只有通过代表。 您应该重新devise您的function或拒绝使用UIAlertView

这不会阻塞,但我已经写了一个子类来添加块风格的语法,这使得它更容易处理buttonClickedAtIndex方法,而不必做一个委托和一大堆的if语句,如果你在一个类中有多个UIAlertViews 。

 #import <UIKit/UIKit.h> @interface UIAlertViewBlock : UIAlertView<UIAlertViewDelegate> - (id) initWithTitle:(NSString *)title message:(NSString *)message block: (void (^)(NSInteger buttonIndex))block cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_AVAILABLE(10_6, 4_0); @end #import "UIAlertViewBlock.h" @interface UIAlertViewBlock() { void (^_block)(NSInteger); } @end @implementation UIAlertViewBlock - (id) initWithTitle:(NSString *)title message:(NSString *)message block: (void (^)(NSInteger buttonIndex))block cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_AVAILABLE(10_6, 4_0) { if (self = [super initWithTitle:title message:message delegate:self cancelButtonTitle:cancelButtonTitle otherButtonTitles:otherButtonTitles, nil]) { _block = block; } return self; } - (void) alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { _block(buttonIndex); } @end 

然后在这里调用它是一些示例代码。 另一个很酷的部分是,因为一个块closures了局部variables,所以我可以访问当我显示UIAlertView时存在的所有状态。 使用传统的委托方法,您必须将所有临时状态存储到类级variables中,才能在委托中调用buttonClickedAtIndex时访问它。 这非常干净。

 { NSString *value = @"some random value"; UIAlertViewBlock *b = [[UIAlertViewBlock alloc] initWithTitle:@"Title" message:@"Message" block:^(NSInteger buttonIndex) { if (buttonIndex == 0) NSLog(@"%@", [value stringByAppendingString: @" Cancel pressed"]); else if (buttonIndex == 1) NSLog(@"Other pressed"); else NSLog(@"Something else pressed"); } cancelButtonTitle:@"Cancel" otherButtonTitles:@"Other", nil]; [b show]; } 

我只是面对同样的问题。 虽然没有解决scheme,但至less有两个解决办法,我想到了。

循环“解决scheme”在你调用UIAlert之后,你开始一个循环,寻找variables对你的对象是全局variables(而不是整个项目,介意你),这个variables是你在UIAlert委托中设置的variables接受答案。 所以基本上,你等待“是== 1,如果不是DoEvents”,并在其上循环。

然后,当你有答案时,在你的代表你A = 1

之前有人说cocoa中没有DoEvents:

 void MyTestClass::DoEvents() {  NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];  NSEvent* event = [NSApp nextEventMatchingMask:NSAnyEventMask    untilDate:[NSDate distantPast]    inMode:NSDefaultRunLoopMode    dequeue:YES];  if (event) {    [NSApp sendEvent:event];    [NSApp updateWindows];  }  [pool release]; } 

委托解决scheme代替在调用Alert的函数中具有处理答案A,B或C的代码,请在委托本身中包含代码。

希望能帮助到你。 我用我的项目中的第二个,它的工作。

我只是偶然发现了这个问题,甚至通过发布进入苹果地狱,我在此宣布这是一个概念certificate:

 @interface EvilShitClass () <UIAlertViewDelegate> @end @implementation EvilShitClass { BOOL _isCanceled, _wasYes; } 

这是一个是/否查询的静态方法:

 + (BOOL)yesNoQueryWithTitle:(NSString*)title text:(NSString*)text { EvilShitClass *shit = [EvilShitClass new]; UIAlertView *alertView = [UIAlertView new]; alertView.delegate = shit; alertView.title = title; alertView.message = text; [alertView addButtonWithTitle:@"Yes"]; [alertView addButtonWithTitle:@"No"]; NSRunLoop *run_loop = [NSRunLoop currentRunLoop]; [alertView show]; while( !shit->_isCanceled ) { BOOL tmp = [run_loop runMode:NSDefaultRunLoopMode beforeDate:[NSDate date]]; } return shit->_wasYes; } 

最后是处理button的代理方法点击并停止runloop处理:

 - (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex { _wasYes = (buttonIndex == 0); _isCanceled = YES; } 

这个工作,但记住:你不应该这样做: – 美丽请不要争论风格和东西,这只是一个5分钟的快速入侵certificate它可以做! 这应该没有弧(新 – > autorelease),但如果我错了,你知道如何处理它;)

免责声明:对于使用此代码段可能对您的应用程序或设备造成的任何可能的损害,我不承担任何责任。 谢谢。

使用带有Joseph的块的UIAlertView,并为其添加一个信号量。 声明一个全局的信号量

 dispatch_semaphore_t generateNotificationsSemaphore; 

并在块处理程序中发出信号

 [alert showWithHandler:^(UIAlertView *alertView, NSInteger buttonIndex) { if (buttonIndex == [alertView cancelButtonIndex]) { } else { } dispatch_semaphore_signal(generateNotificationsSemaphore); }]; 

在调用showWithHandler之后,使用信号量添加一个等待循环

 while (dispatch_semaphore_wait(generateNotificationsSemaphore, DISPATCH_TIME_NOW )) { [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:20]]; } 

您的实际超时值可能会根据您的需要而有所不同。