我有一个Catch 22问题,我无法摆脱,我正在使用UIAlertCOntroller向用户显示信息,并根据我需要采取一些行动的答案
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;
}
}
我遇到的问题是,最后一个return语句似乎是在完成块完成之前运行的,我希望返回条件是用户操作,但如果我将返回值设置为Yes alertAction则代码如下在方法运行之前,用户有机会选择是/否所以我卡住了我需要最后一次返回来停止下面的代码运行但同时我需要等待完成块完成?如何处理这种情况,以便我的代码在整个代码块下面只在用户选择操作后运行?
答案 0 :(得分:0)
您可以尝试将其附加到根视图控制器,例如:
//Step 4: Present the alert to the user
UIViewController *controller = [UIApplication sharedApplication].delegate.window.rootViewController;
[controller presentViewController:userInfoCheck animated:YES completion:nil];
return;
答案 1 :(得分:0)
Any time you see APIs that accept "handler" blocks, it's best to assume they run asynchronously. That means that the order of statements in your source code is not the order of operations.
In this case...
presentViewController
returns immediately (and your function returns immediately thereafter), causing the alert to show.This means that whatever logic you want to use for responding to the user's alert choice cannot be written in the method body that presents the alert. You'll need to arrange for such code to run as a result of your alert action handlers. A pseudocode-ish example:
- (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];