2017-11-07 10 views
0

は、私は、私は、ユーザーに情報を表示するためにUIAlertCOntrollerを使用していますから抜け出すと、私は私が午前問題があるいくつかのアクションこのCatch 22の状況から抜け出す方法は?

if([NWTillHelper finishTransactionWithoutEmail] != 1) { 
     if([NWTillHelper getCrmId] == nil) { 
      //Step 1: Create a UIAlertController 
      UIAlertController *userInfoCheck = [UIAlertController alertControllerWithTitle:@"No Customer Email!" 
                        message: @"Do you want to proceed without customer email? No receipt will be sent out in this case!" 
                      preferredStyle:UIAlertControllerStyleAlert]; 

      //Step 2: Create a UIAlertAction that can be added to the alert 
      UIAlertAction *Yes = [UIAlertAction 
            actionWithTitle:@"Yes" 
            style:UIAlertActionStyleDefault 
            handler:^(UIAlertAction * action) 
            { 
             NSUserDefaults *tillUserDefaults = [NSUserDefaults standardUserDefaults]; 
             [tillUserDefaults setInteger:1 forKey:@"finishTransactionWithoutEmail"]; 
             [tillUserDefaults synchronize]; 
             [userInfoCheck dismissViewControllerAnimated:YES completion:nil]; 
            }]; 

      UIAlertAction *No = [UIAlertAction 
           actionWithTitle:@"No" 
           style:UIAlertActionStyleDefault 
           handler:^(UIAlertAction * action) 
           { 
            [userInfoCheck dismissViewControllerAnimated:YES completion:nil]; 
           }]; 

      //Step 3: Add the UIAlertAction ok that we just created to our AlertController 
      [userInfoCheck addAction: Yes]; 
      [userInfoCheck addAction: No]; 

      //Step 4: Present the alert to the user 
      [self presentViewController:userInfoCheck animated:YES completion:nil]; 
      return; 
     } 
    } 

を取る必要が回答に基づいてすることはできませんキャッチ22の問題が生じています完了ブロックが終了する前に最後のreturnステートメントが実行されているように見せて、ユーザーアクションで条件付きにしたい場合は、Yes alertActionにリターンを入れると、メソッドの下のコードがユーザーの前に実行されますはい/いいえを選択するチャンスがあるので、私は立ち往生しています。私は最後の復帰を実行してそのコードを停止する必要がありますが、同時に完了ブロックが完了するまで待つ必要がありますか?ユーザーがアクションを選択した後でのみ、このコードブロック全体の下にあるコードが実行されるように、この状況をどのように処理できますか?

答えて

0

あなたは「ハンドラ」のブロックを受け入れるのAPIを参照してくださいいつでも、それは彼らが非同期で実行を前提とするのがベストです。つまり、ソースコード内の文の順序は操作の順序ではありません。この場合

...

  1. presentViewController戻り、すぐにアラートを表示するように引き起こして、(そしてあなたの関数は、その後すぐに戻ります)。
  2. ユーザーはアラートボックスを見ながらそこに座っている間、アプリはメインループを回転させ続けます。 UIKitは目に見える効果がなくてもトラックをタッチするので、UIの他の要素がアラートの後ろに表示されたり、ネットワークアクティビティなどのユーザー以外の入力に反応したりする可能性があります。
  3. アラートボックスのボタンをタップすると、UIKitはYesまたはNoのいずれかの完了ハンドラを実行します。

これは、ユーザーの警告選択に応答するために使用したいものは何でもロジックアラートを提示する方法本体に書き込むことができないことを意味します。アラートアクションハンドラの結果として実行するようなコードを用意する必要があります。擬似コードの例:

- (void)handleEmailChoice:(BOOL)proceedWithoutEmail { 
    // do whatever depends on user choice 
} 

// elsewhere 
UIAlertController *userInfoCheck = [UIAlertController alertControllerWithTitle:/*...*/]; 
UIAlertAction *yes = [UIAlertAction actionWithTitle:@"Yes" 
           style:UIAlertActionStyleDefault 
           handler:^(UIAlertAction * action) 
           { 
           // set defaults, dismiss alert, then: 
           [self handleEmailChoice:YES]; 
           }]; 

UIAlertAction *no = [UIAlertAction actionWithTitle:@"No" 
          style:UIAlertActionStyleDefault 
          handler:^(UIAlertAction * action) 
          { 
           // dismiss alert, then: 
           [self handleEmailChoice:NO]; 
          }]; 

[userInfoCheck addAction: yes]; 
[userInfoCheck addAction: no]; 
[self presentViewController:userInfoCheck animated:YES completion:nil]; 
0

あなたは、ルートビューコントローラに添付しようとすることができ、例えば:

//Step 4: Present the alert to the user 
UIViewController *controller = [UIApplication sharedApplication].delegate.window.rootViewController; 
[controller presentViewController:userInfoCheck animated:YES completion:nil]; 
return; 
+0

本当に申し訳ありませんが、どのように役立ちますか?もう少し説明すればいいかもしれません –

+0

あなたの 'self'は戻り値の後に破棄されて、それに付随するすべてのものを破壊するかもしれません。ルートビューコントローラはより永続的です。 –

関連する問題