I've created a test application to understand how views/viewcontrollers work and how to navigate between them programmatically without a storyboard or a nib.
I've basically set up a rootViewController
called Viewcontroller which is set in the AppDelegate
.
This view presents view1 on startup which contains a uibutton which calls the notification in the rootViewController
to present view2. However when I do this I keep getting the warning:
Warning: Attempt to present <View1: 0x7be66c80> on <ViewController: 0x7be62980> whose view is not in the window hierarchy!
My code for the controlling viewcontroller is as follows:
#import "ViewController.h" #import "View1.h" #import "View2.h" @interface ViewController () @end @implementation ViewController -(void) loadView{ [super loadView]; } -(void)viewDidAppear:(BOOL)animated{ NSLog(@"View appeared"); [[NSNotificationCenter defaultCenter] removeObserver:self name:@"view1" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(view1:) name:@"view1" object:nil]; [[NSNotificationCenter defaultCenter] removeObserver:self name:@"view2" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(view2:) name:@"view2" object:nil]; [self showView1]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } -(void)view1:(NSNotification*) notification{ NSLog(@"Showing view1"); [self dismissViewControllerAnimated:YES completion:nil]; [self showView1]; } -(void)showView1{ dispatch_async(dispatch_get_main_queue(), ^{ [self.view.window.rootViewController presentViewController:[[View1 alloc]init] animated:YES completion:nil]; }); } -(void)view2:(NSNotification*) notification{ NSLog(@"Showing view2"); [self dismissViewControllerAnimated:YES completion:nil]; [self showView2]; } -(void)showView2{ dispatch_async(dispatch_get_main_queue(), ^{ [self presentViewController:[[View1 alloc]init] animated:YES completion:nil]; }); } @end
Edit:I forgot to mention that view1 displays initially without any errors or problems.
Edit: the code for view1 and view2 are exactly identical except that they send different notifications:
#import "View1.h" @interface View1 () @end @implementation View1 - (void)loadView { [super loadView]; self.view.frame = [[UIApplication sharedApplication].keyWindow bounds]; // Do view setup here. UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button addTarget:self action:@selector(touchedLogin:) forControlEvents:UIControlEventTouchUpInside]; [button setTitle:@"Login" forState:UIControlStateNormal]; button.layer.cornerRadius=1; button.frame = CGRectMake(self.view.bounds.size.width/2-100, self.view.bounds.size.height-200, 200, 60.0); [button setTitleEdgeInsets:UIEdgeInsetsMake(5.0, 0.0, 0.0, 0.0)]; //[_window setBackgroundColor:[UIColor whiteColor]]; [self.view addSubview:button]; } -(void)touchedLogin:(id*)sender{ [[NSNotificationCenter defaultCenter] postNotificationName:@"view2" object:nil]; } @end