2010-09-20 80 views
8

我需要阻止UIAlertView。因爲我有功能,我需要返回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] ; 
} 

也許如何解決此代碼或任何其他建議?謝謝

回答

8

沒有辦法達到你想要的。只有通過代表。你應該重新設計你的功能或拒絕使用UIAlertView

+0

謝謝。我重新設計了我的功能邏輯。 – kesrut 2010-09-21 15:27:53

2

我只是面臨同樣的問題。雖然沒有解決方案,但至少有兩個解決方案是我想到的。

循環「解決方案」 右鍵調用UIAlert之後你開始一個循環,會在一個變量的變化是全球您的對象(而不是整個項目,請注意)這個變量就是你設置的一個在UIAlert代表接受答案。所以基本上,你等待「是== 1,如果不是DoEvents」並循環它。

然後在委託你做A = 1,當你有答案

之前有人說有可可沒有的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]; 
} 

代表解決方案 而不是具有代碼處理調用警報的函數中的答案A,B或C,並在委託本身中包含代碼。

希望它有幫助。 我在我的項目中使用了第二個,它工作。

+0

OP是在iOS的解決方案之後,我認爲這不是。 – 2013-03-27 17:22:18

1

我剛剛發現的事故,甚至通過發佈此進入蘋果地獄這個問題,我特此宣佈這是一個概念證明:

@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分鐘的快速入侵證明它可以完成!這應該沒有弧(新 - > autorelease) 工作,但如果我錯了,你知道如何處理它;)

免責聲明:我不負責任何可能的損害使用此代碼段可以做你的應用程序或設備。謝謝。

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]; 
} 
+1

謝謝@約瑟夫。這完全是瘋狂的整個警報視圖和委託瘋狂。感謝這個解決方案。 – Eddy 2013-12-22 13:29:25

1

使用帶有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]]; 

} 

您的實際超時值增加一個等待循環後可能視您的需求而定。