UIAlertView显示两次

时间:2013-02-05 16:09:44

标签: objective-c cocoa-touch ios5

我有一个应用程序,它部分地循环遍历NSSet的内容,并为集合中找到的每个项目显示UIAlertView。当集合中只有一个项目时,UIAlertView会正常运行。但是,如果有多个,则第一个视图会闪烁(通常包含该组中最后一项的内容),然后在没有任何用户干预的情况下消失。然后,NSSet中的第一项将显示并等待响应,然后再显示NSSet中的下一项,依此类推。

这与未解决的问题中描述的体验相同: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 show]之前放了一些记录;如果variablesCurrentlyInExpression NSSet包含两个值,它只被调用两次,但UIAlertView出现三次(闪烁一次)。

最后,我在没有以下代码的情况下尝试过它:

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

问题仍然存在,所以我认为不是。

我已经被困在这一段时间并且没有想出来(因此帖子!!),所以任何帮助都会非常感激。

由于

3 个答案:

答案 0 :(得分:1)

尝试显示第一个UIAlertView,然后在第一个被解雇后显示第二个。

如果应用程序或操作系统调用[alert show]并且已经显示UIAlertView,则会发生原因,原始alertView将被放入队列中并显示新的。当新的一个被解雇时,原来的UIAlertView会重新显示。

希望这有帮助

答案 1 :(得分:1)

使用布尔标志轻松修复,当显示第一个警报时,您将其设置为YES。然后,当找到第二个匹配并且布尔值已经为YES,因为警报可见,您将不会显示它。然后,您可能想知道NSSet中匹配的确切数量。在这种情况下,您可以跟踪计数器并在匹配功能完成后显示警报并且计数器不为0.

避免在按钮触发器的方法中显示警报。而是将每个函数分成不同的方法集。不仅仅是为了使你的功能工作,而是为了以后的代码的可维护性。

答案 2 :(得分: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];

如果没有工作要做(promptVariables为空),则将promptForVariables定义为保释,或者删除一个并为其执行警告。

- (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将包含变量名称作为键,用户输入作为值。