2015-01-22 4 views
1

다음 코드에서 특정 이벤트가 발생하면 handleEvent 메서드를 호출하려고합니다. 이를 위해 이벤트가 발생한 위치 (아래 코드에 표시되지 않음)에 알림을 게시하여 observer와 handleEvent에서 알림을 관찰합니다 (아래 코드 참조).AlertViewController - 뷰가 윈도우 계층 구조에 없음 문제

나는 그것을받을 수 있도록 팝업 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]; 
    } 
} 
+1

'[인스턴스 showAlert]'를 사용하면 어떻습니까? – gabbler

+0

@ gabbler 귀하의 의견은 내가 변경 한 내용을 변경하는 데 도움이됩니다. showAlert 메서드를 호출했지만 여전히 UIAlertView가 표시되지 않습니다 –

+0

'showAlert'를 호출하기 위해'handleEvent :'에서 변경 한 사항은 공유 인스턴스가 이미 존재할 경우에만 작동합니다 창조되고 제시된. – rmaddy

답변

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 메서드를 추가하고 알림 옵저버를 등록 취소하십시오.
+0

크래시보고와 관련된 제품을 개발 중입니다. 뷰를로드하기 전에 옵저버를 등록하는 것이 중요합니다. 그래서 ViewDidLoad 메서드에서 observer를 등록 할 수 있습니다. –

+0

맞아, 그건 내가 말한거야. 관찰자를'viewDidLoad'에 등록하십시오. – rmaddy

+0

죄송합니다. 잘못 입력했는데 ViewDidLoad 메서드에서 관찰자를 등록 할 수 없습니다.내 알림은 ViewDidLoad가 발생하기 전에 게시됩니다. 그래서 제 경우에는 관찰자가 ViewDidLoad 전에 등록되어야합니다. –