我需要阻止make UIAlertView
。因为我有功能,我需要返回UIAlertView
选项。但问题是在显示UIAlertView
之后我的函数代码正在执行,所以我无法捕获UIAlertView
选项(我可以在委托方法中执行,但我需要返回函数结果)。
我尝试使用UIAlertVIew
进行NSCondition
屏蔽。但是代码不起作用。
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] ;
}
也许如何修复此代码或任何其他建议?感谢
答案 0 :(得分:8)
没有办法实现你想要的。只有通过代表。你应该重新设计你的功能或拒绝使用UIAlertView
答案 1 :(得分:5)
这不会阻止它,但是我编写了一个子类来添加块样式语法,这使得处理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
然后在这里调用它是一些示例代码。另一个很酷的部分是,因为一个块关闭局部变量,我可以访问我显示UIAlertView时存在的所有状态。使用传统的委托方法,您必须将所有临时状态存储到类级变量中,以便在委托中对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];
}
答案 2 :(得分:2)
我刚遇到同样的问题。虽然没有解决方案,但我至少有2种解决方法。
循环&#34;解决方案&#34; 在调用UIAlert之后,您启动一个循环,查找对象的全局变量(而不是整个项目,请注意)变量是您在UIAlert委托中设置的变量。所以基本上你等待&#34; A == 1,如果不是DoEvents&#34;然后循环它。
然后在代表上,当你得到答案时,你将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];
}
代表解决方案 而不是在调用Alert的函数中使用处理答案A,B或C的代码,而是在委托本身中使用代码。
希望它有所帮助。 我在我的项目中使用了第二个,它起作用了。
答案 3 :(得分:1)
我偶然发现了这个问题,甚至通过发布这个问题进入Apple地狱,我特此声明这是一个概念证据:
@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;
}
最后处理按钮点击和的委托方法 停止runloop处理:
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex {
_wasYes = (buttonIndex == 0);
_isCanceled = YES;
}
这有效但记住:你不应该这样做:-D 相当请不要争论风格和东西,它只是一个5分钟快速黑客证明它可以做!这应该没有ARC(新的 - &gt; autorelease) 但如果我错了你知道如何处理它;)
免责声明:对于使用此代码段对您的应用程序或设备造成的任何可能的损害,我概不负责。谢谢。
答案 4 :(得分:1)
将UIAlertView与来自Joseph的块一起使用,并为其添加一个信号量。 声明全局信号量
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]];
}
根据您的需要,您的实际超时值可能会有所不同。