我有一个应用程序,它部分地循环遍历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;
问题仍然存在,所以我认为不是。
我已经被困在这一段时间并且没有想出来(因此帖子!!),所以任何帮助都会非常感激。
由于
答案 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将包含变量名称作为键,用户输入作为值。