0

NSSet のコンテンツを部分的にループし、セット内で見つかった各アイテムの UIAlertView を表示するアプリケーションがあります。セットに項目が 1 つしかない場合、UIAlertView は適切に動作します。ただし、複数ある場合は、最初のビューがフラッシュアップし (通常はセット内の最後のアイテムの内容で)、ユーザーの介入なしに消えます。NSSet の最初の項目が表示され、応答を待ってから、NSSet の次の項目が表示されます。

これは、この未解決の質問で説明されているのと同じエクスペリエンスです: IPHONE: カスタム関数/IBAction で UIAlertView が 2 回呼び出されました

コードは次のとおりです。

#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 に 2 つの値が含まれている場合に 2 回だけ呼び出されますが、UIAlertView は 3 回表示されます (1 回点滅します)。

最後に、次のコードなしで試しました:

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

問題はまだ発生しているので、そうではないと思います。

私はこれにしばらく立ち往生していて、それを理解していませんでした(したがって、投稿!!)ので、どんな助けも大歓迎です.

ありがとう

4

3 に答える 3

1

最初のUIAlertViewを表示してから、最初のUIAlertViewが閉じられた後に2番目のUIAlertViewを表示してみてください。

アプリまたはOSが[alertshow]を呼び出し、UIAlertViewがすでに表示されている場合、元のalertViewがキューに入れられ、新しいalertViewが表示されます。新しいものが閉じられると、元のUIAlertViewが再表示されます。

お役に立てれば

于 2013-02-05T16:42:45.417 に答える
1

最初のアラートが表示されたときに YES に設定するブール値フラグで簡単に修正できます。次に、2 番目の一致が見つかり、ブール値がすでに YES の場合、アラートが表示されているため表示されません。次に、NSSet 内の正確な一致数を知りたい場合があります。その場合、カウンターで追跡し、一致関数が実行されてカウンターが 0 でなくなった後にアラートを表示します。

ボタン トリガーのメソッド内でアラートを表示しないようにします。代わりに、すべての関数を異なるメソッド セットに分割します。関数を機能させるだけでなく、後でコードを保守するためでもあります。

于 2013-02-05T16:51:29.750 に答える
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が空の場合)にbailするように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にはキーとして変数名が含まれ、値としてユーザー入力が含まれます。

于 2013-02-05T17:00:23.433 に答える