2013-02-05 125 views
0

我有一個應用程序部分循環遍歷NSSet的內容,併爲該集合中的每個項目顯示一個UIAlertView。當集合中只有一個項目時,UIAlertView正常運行。但是,如果有多個視圖,則第一個視圖會閃爍(通常是集合中最後一個項目的內容),然後在沒有任何用戶干預的情況下消失。 NSSet中的第一項將顯示並等待響應,然後顯示NSSet中的下一個項目,依此類推。UIAlertView顯示兩次

這是相同的經驗,在這個懸而未決的問題被描述:IPHONE: UIAlertView called twice in a custom function/IBAction

下面的代碼:

#import "CalcViewController.h" 

@interface CalcViewController() 
@property (nonatomic) int variablesCount; 
@property (nonatomic, strong) NSMutableDictionary *variablesSet; 
@end 

@implementation CalcViewController 

- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 
    self.variablesSet = [[NSMutableDictionary alloc] init]; 
} 


- (IBAction)variablePressed:(UIButton *)sender 
{ 
    [[self calcModel] setVariableAsOperand:sender.titleLabel.text]; 
    self.expressionDisplay.text = [[self calcModel] descriptionOfExpression:self.calcModel.expression]; 
} 

- (IBAction)solveExpressionPressed:(UIButton *)sender { 
    self.variablesCount = 0; 
    [self.variablesSet removeAllObjects]; 

    NSSet *variablesCurrentlyInExpression = [[NSSet alloc] initWithSet:[CalcModel variablesInExpression:self.calcModel.expression]]; 
    self.variablesCount = [variablesCurrentlyInExpression count]; 

    if (variablesCurrentlyInExpression){ 
     for (NSString *item in variablesCurrentlyInExpression) { 
      UIAlertView *alertDialog; 
      alertDialog = [[UIAlertView alloc] initWithTitle:@"Enter value for variable" 
               message:item 
               delegate:self 
               cancelButtonTitle:@"OK" 
               otherButtonTitles:nil]; 

      alertDialog.alertViewStyle=UIAlertViewStylePlainTextInput; 
      UITextField * alertTextField = [alertDialog textFieldAtIndex:0]; 
      alertTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation; 
      [alertDialog show]; 
     } 

    } 
} 

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ 
     if (buttonIndex == 0){ 
     if ([[alertView textFieldAtIndex:0] text]){   
      self.variablesSet[alertView.message] = [[alertView textFieldAtIndex:0] text]; 
     } 
    } 

    if ([self.variablesSet count] == self.variablesCount){ 
     NSLog(@"time to solve"); 
     [[self calcDisplay] setText:[NSString stringWithFormat:@"%g", [CalcModel evaluateExpression:self.calcModel.expression usingVariableValues:self.variablesSet]]]; 
    } 
} 

我已經籤背後觸發solveExpressionPressed方法的按鈕IBActions和是唯一存在的。我還在[alertDialog顯示]之前放置了一些日誌記錄;行,並且它只在variablesCurrentlyInExpression NSSet包含兩個值時調用兩次,但UIAlertView出現三次(閃爍一次)。

最後,我已經試過了沒有下面的代碼:

  UITextField * alertTextField = [alertDialog textFieldAtIndex:0]; 
      alertTextField.keyboardType = UIKeyboardTypeNumbersAndPunctuation; 

和問題仍然存在,所以我不認爲這是。

我一直卡在這一段時間,還沒有想通了(因此後!),所以任何幫助將不勝感激。

由於

+0

當不止一次滿足條件時,您想要什麼警報視圖行爲? – danh

+0

對於表達式中的每個變量,我提示用戶需要將該值分配給該變量。然後,我將這些變量:值對添加到字典中,並將它們傳遞給模型以解決表達式。有沒有更好的方法從用戶那裏獲取一組值(在設計時你不知道表達式中有多少變量)?我會給你的建議一個去,回到我有多成功。歡呼聲 – cullener

回答

0

得到這個工作,你需要保留一些額外的狀態類,像這樣...

@property (strong, nonatomic) NSMutableSet *promptVariables; 
@property (strong, nonatomic) NSString *promptVariable; 
@property (strong, nonatomic) NSMutableDictionary *promptResults; 

,也許可以與通過保持一定的模型,因爲它是不太逃脫(或者你現在巧妙地在警報視圖消息中隱藏一點點),但我會使用所有新變量來清晰。

當你想做出幾個提示,設置你的狀態,像這樣...

self.promptVariables = [[NSSet alloc] initWithSet:[CalcModel variablesInExpression:self.calcModel.expression]]; 
[self promptForVariables]; 

定義promptForVariables保釋,如果它沒有工作要做(promptVariables爲空),或刪除一個併爲它做了警報。

- (void)promptForVariables { 

    if (![self.promptVariables count]) return; 
    self.promptResults = [NSMutableDictionary dictionary]; 

    self.promptVariable = [self.promptVariables anyObject]; 
    [self.promptVariables removeObject:self.promptVariable]; 

    // do your alert here, I won't repeat your code 
} 

然後當警報完成後,按照您的要求處理結果並再次調用promptForVariables。下一次,既然你已經改變了狀態,那麼它的工作量就會減少。

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex{ 
     if (buttonIndex == 0){ 
     if ([[alertView textFieldAtIndex:0] text]){   
      [self.promptResults setValue:[[alertView textFieldAtIndex:0] text] forKey:self.promptVariable]; 
     } 
     [self performSelector:@selector(promptForVariables) withObject:nil afterDelay:0.0]; 
    } 
} 

完成此操作後,promptResults將包含變量名稱作爲鍵和用戶輸入值。

+0

優秀的東西......完美的工作(除了在最終代碼部分添加一個點或方括號「[self promptResults」),感謝您的幫助 – cullener

+0

很高興聽到,編輯修復語法。一個改變 - 在後續的promptForVariables調用上執行選擇器將把控制返回到事件循環,以便ui可以更新。 – danh

1

嘗試示出了第一和UIAlertView中然後示出了第一被駁回之後的第二個。

發生的情況是,如果應用程序或操作系統調用[alert show]並且已經顯示UIAlertView,則將原始alertView放入隊列中並顯示新的alertView。當新的解除時,原始的UIAlertView被重新顯示。

希望這有助於

+0

你是指點你的指示。我只能將一個答案標記爲已接受的答案,所以我與danh一起提供了全面的細節。非常感謝您的幫助......您的描述非常清晰。 – cullener

1

容易固定與你上示出第一警報設置爲YES時一個布爾標誌。然後,當找到第二個匹配,並且由於警報可見,布爾值已經爲YES,您將不會顯示它。然後你又想知道NSSet中確切的匹配數量。在這種情況下,您跟蹤一個計數器,並在匹配功能完成且計數器不爲0後顯示警報。

避免在按鈕觸發器的方法內顯示警報。而是將每個功能分成不同的方法組。不僅僅是爲了讓你的功能工作,而且還要保證代碼的可維護性。

+0

感謝您的幫助......這可能會有效,但我與丹作爲接受的答案。 – cullener