在下面的代码中,我仅在发生特定事件时才尝试调用handleEvent方法。为此,我在事件发生的地方发布了一个通知(下面的代码未显示),以便观察者和handleEvent可以观察到该通知(如下代码)。

我想要一个警报viewController弹出并输入文本,以便我可以接收它。
但我得到以下错误:

Warning: Attempt to present <UIAlertController: 0x7f9d1347ed90> on <MSMDemoFirstViewController: 0x7f9d1347e920> whose view is not in the window hierarchy!

尽管我正在使用单例,但我无法理解,但无法正确获取alertViewController。任何帮助都会很有用。
   #import "MSMDemoFirstViewController.h"
#import "CAMDOReporter.h"
static MSMDemoFirstViewController * instance = nil;
@interface MSMDemoFirstViewController ()

@end

@implementation MSMDemoFirstViewController

+ (MSMDemoFirstViewController *)sharedInstance {
    // Singleton implementation
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        if (instance == nil) {
            instance = [[MSMDemoFirstViewController alloc] init];
        }
    });
    return instance;
}

+(void)load{
[[NSNotificationCenter defaultCenter] addObserver:[MSMDemoFirstViewController sharedInstance] selector:@selector(handleEvent:) name:EVENT_OCCURRED object:nil];
}


+(void) initialize{

}
- (void) viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];
    //[[CAMDOReporter sharedInstance] startApplicationTransaction:@"DemoEventApplicationTransaction"];
   // [self showAlert];
}

-(void)showAlert{
    NSLog(@"2ew");
    NSString *title = NSLocalizedString(@"A Short Title Is Best", nil);
    NSString *message = NSLocalizedString(@"A message should be a short, complete sentence.", nil);
    NSString *cancelButtonTitle = NSLocalizedString(@"Cancel", nil);
    NSString *otherButtonTitle = NSLocalizedString(@"OK", nil);

    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];

    [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
        // If you need to customize the text field, you can do so here.
    }];

    // Create the action.
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        NSLog(@"The simple alert's cancel action occured.");
    }];

    UIAlertAction *otherAction = [UIAlertAction actionWithTitle:otherButtonTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        NSLog(@"The \"Text Entry\" alert's other action occured.");
    }];
    // Add the action.
    [alertController addAction:cancelAction];
    [alertController addAction:otherAction];
    [self presentViewController:alertController animated:YES completion:nil];
}

-(void)handleEvent:(NSNotification *)note{
    NSLog(@"Handle Crash Event");
    NSDictionary *crashData  = [note userInfo];
    if(crashData !=nil){
        //Implement any UI Logic to get any response from the user. e.g. AlertView, TextFields.
        //Once the feedback is received convert it into NSString and send the data.
        // Show a text entry alert with two custom buttons.
        [[MSMDemoFirstViewController sharedInstance] showAlert];
        NSString *feedback=[[NSUserDefaults standardUserDefaults] objectForKey:@"crashDetails"];
        [[CAMDOReporter sharedInstance] setCustomerFeedback:feedback];
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

现在我得到的输出是:
2015-01-21 20:17:45.762 CAMAADemo[18891:1558312] Handle Crash Event
2015-01-21 20:17:45:762 CAMAADemo[18891:1807] Posting Notification about crash
2015-01-21 20:17:45.762 CAMAADemo[18891:1558312] 2ew
2015-01-21 20:17:45.778 CAMAADemo[18891:1558312] Warning: Attempt to present <UIAlertController: 0x7ff5d2273580> on <MSMDemoFirstViewController: 0x7ff5d2204be0> whose view is not in the window hierarchy!

这意味着该调用将要使用showAlert方法,但随后却遇到了同样的错误。

甚至以下代码也无济于事。
-(void)viewDidLoad{
    [super viewDidLoad];
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleCrashEvent:) name:CAMAA_CRASH_OCCURRED object:nil];
}
-(void)showAlert{
    NSLog(@"2ew");
    NSString *title = NSLocalizedString(@"A Short Title Is Best", nil);
    NSString *message = NSLocalizedString(@"A message should be a short, complete sentence.", nil);
    NSString *cancelButtonTitle = NSLocalizedString(@"Cancel", nil);
    NSString *otherButtonTitle = NSLocalizedString(@"OK", nil);

    UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];

    [alertController addTextFieldWithConfigurationHandler:^(UITextField *textField) {
        // If you need to customize the text field, you can do so here.
    }];

    // Create the action.
    UIAlertAction *cancelAction = [UIAlertAction actionWithTitle:cancelButtonTitle style:UIAlertActionStyleCancel handler:^(UIAlertAction *action) {
        NSLog(@"The simple alert's cancel action occured.");
    }];

    UIAlertAction *otherAction = [UIAlertAction actionWithTitle:otherButtonTitle style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
        NSLog(@"The \"Text Entry\" alert's other action occured.");
    }];
    // Add the action.
    [alertController addAction:cancelAction];
    [alertController addAction:otherAction];
    [self presentViewController:alertController animated:YES completion:nil];
}

-(void)handleCrashEvent:(NSNotification *)note{
    NSLog(@"Handle Crash Event");
    NSDictionary *crashData  = [note userInfo];
    if(crashData !=nil){
        //Implement any UI Logic to get any response from the user. e.g. AlertView, TextFields.
        //Once the feedback is received convert it into NSString and send the data.
        // Show a text entry alert with two custom buttons.
        [self showAlert];
        NSString *feedback=[[NSUserDefaults standardUserDefaults] objectForKey:@"crashDetails"];
        [[CAMDOReporter sharedInstance] setCustomerFeedback:feedback];
    }
}

最佳答案

代码的问题是您创建了一个全新的视图控制器,并显示了来自新控制器的警报。但是没有显示该控制器,因此显示错误消息。

修复此代码的正确方法是从实际显示的视图控制器显示警报。

为此,将实际的视图控制器实例注册为通知处理程序,而不是在load方法中注册该类。

进行以下更改:

  • 消除load方法。
  • 将对[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleEvent:) name:EVENT_OCCURRED object:nil];的调用移至viewDidLoad方法。
  • handleEvent:更改为实例方法。
  • [[[self alloc]init] showAlert];更改为[self showAlert];
  • 添加dealloc方法并取消注册通知查看器。
  • 关于ios - AlertViewController-其 View 不在窗口层次结构中,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/28081097/

    10-14 20:40