AlertViewController - 其视图不在窗口层次结构问题中

时间:2015-01-22 04:01:18

标签: ios uialertview

在下面的代码中,我试图仅在特定事件发生时调用方法handleEvent。为此,我发布事件发生的通知(未在下面的代码中显示),以便观察者和handleEvent观察通知(如下面的代码所示)。

我想要一个警报viewController弹出并获取文本条目,以便我可以接收它。 但是我收到了以下错误:

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

我无法理解虽然我使用的是singleton,但我无法正确获取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];
    }
}

1 个答案:

答案 0 :(得分:3)

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

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

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

进行以下更改:

  1. 消除load方法。
  2. 将来电[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleEvent:) name:EVENT_OCCURRED object:nil];移至viewDidLoad方法。
  3. handleEvent:更改为实例方法。
  4. [[[self alloc]init] showAlert];更改为[self showAlert];
  5. 添加dealloc方法并取消注册通知观察者。