2013-02-05 90 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