Ios 不断更改视图使我尝试在视图不在窗口层次结构中的vc上显示vc1

Ios 不断更改视图使我尝试在视图不在窗口层次结构中的vc上显示vc1,ios,objective-c,viewcontroller,presentviewcontroller,Ios,Objective C,Viewcontroller,Presentviewcontroller,我创建了一个测试应用程序,以了解视图/视图控制器如何工作,以及如何在没有故事板或nib的情况下以编程方式在它们之间导航 我基本上设置了一个名为Viewcontroller的rootViewController,它是在AppDelegate中设置的 此视图在启动时显示view1,其中包含一个UI按钮,该按钮调用rootViewController中的通知来显示view2。然而,当我这样做时,我不断得到警告: Warning: Attempt to present <View1: 0x7be6

我创建了一个测试应用程序,以了解视图/视图控制器如何工作,以及如何在没有故事板或nib的情况下以编程方式在它们之间导航

我基本上设置了一个名为Viewcontroller的
rootViewController
,它是在
AppDelegate
中设置的

此视图在启动时显示view1,其中包含一个UI按钮,该按钮调用
rootViewController
中的通知来显示view2。然而,当我这样做时,我不断得到警告:

Warning: Attempt to present <View1: 0x7be66c80> on <ViewController: 0x7be62980> whose view is not in the window hierarchy!
警告:尝试显示其视图不在窗口层次结构中的对象!
控制viewcontroller的代码如下所示:

#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 #导入“ViewController.h” #导入“View1.h” #导入“View2.h” @界面视图控制器() @结束 @实现视图控制器 -(void)负荷视图{ [超级加载视图]; } -(无效)视图显示:(BOOL)动画{ NSLog(@“视图出现”); [[NSNotificationCenter defaultCenter]removeObserver:self name:@“view1”对象:nil]; [[NSNotificationCenter defaultCenter]添加观察者:自选择器:@selector(view1:)名称:@“view1”对象:nil]; [[NSNotificationCenter defaultCenter]removeObserver:self name:@“view2”对象:nil]; [[NSNotificationCenter defaultCenter]添加观察者:自选择器:@selector(view2:)名称:@“view2”对象:nil]; [自我展示1]; } -(无效)未收到记忆警告{ [超级记忆警告]; //处置所有可以重新创建的资源。 } -(无效)视图1:(NSNotification*)通知{ NSLog(“显示视图1”); [自我解除视图控制器激活:是完成:无]; [自我展示1]; } -(无效)showView1{ dispatch\u async(dispatch\u get\u main\u queue()^{ [self.view.window.rootViewController presentViewController:[[View1 alloc]init]已设置动画:是完成:无]; }); } -(无效)视图2:(NSNotification*)通知{ NSLog(“显示视图2”); [自我解除视图控制器激活:是完成:无]; [自我展示2]; } -(无效)showView2{ dispatch\u async(dispatch\u get\u main\u queue()^{ [self-presentViewController:[[View1 alloc]init]已设置动画:是完成:无]; }); } @结束 编辑:我忘了提到view1最初显示时没有任何错误或问题

编辑:view1和view2的代码完全相同,只是它们发送不同的通知:

#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 #导入“View1.h” @界面视图1() @结束 @实现视图1 -(void)负荷视图{ [超级加载视图]; self.view.frame=[[UIApplication sharedApplication].keyWindow边界]; //请在此处查看设置。 UIButton*button=[UIButton button类型:UIButtonyPeroundRect]; [按钮添加目标:自我 操作:@选择器(touchedLogin:) forControlEvents:UIControlEventTouchUpInside]; [按钮设置标题:@“登录”状态:UIControlStateNormal]; button.layer.cornerRadius=1; button.frame=CGRectMake(self.view.bounds.size.width/2-100,self.view.bounds.size.height-20020060.0); [按钮设置标题插图:UIEdgeInsetsMake(5.0,0.0,0.0,0.0)]; //[_windowsetbackgroundcolor:[UIColor whiteColor]]; [self.view addSubview:按钮]; } -(无效)touchedLogin:(id*)发件人{ [[NSNotificationCenter defaultCenter]postNotificationName:@“view2”对象:nil]; } @结束
之所以出现此错误,是因为您正在使用
动画关闭View1,然后立即调用showView2(它实际上显示了View1,因为在该方法中有
[View1 alloc]init]
)。因为动画需要一些时间,所以您尝试在View1仍在屏幕上时显示View1,而不是
ViewController
。一般来说,这样一个接一个地做解雇和陈述不是个好主意。我想如果你在没有生气的情况下解雇我可能会有效果(尽管我从来没有这样做过)

如果在View1中按下按钮时出现错误,则需要在该按钮的操作方法中显示代码。我已经添加了代码。两个视图都相同,只是另一个视图发送通知以显示另一个视图。我已尝试删除所有动画,但仍然出现错误。我还尝试过在没有任何异常的情况下,对解雇和演示文稿使用dispatch asyncsuccess@thegalah是的,我不确定那会起作用。在代码中不需要使用dispatch\u async,因为所有内容都在主线程上。你的整个方法都不好。不要在解雇后立即做陈述。如果要从View1转到View2,请让View1显示View2。此外,像您这样使用通知也不是最好的方式。当您有多个控制器需要通知某些操作时,而不仅仅是像这里这样的一个控制器时,最好使用它们。我将如何在视图之间导航。我是新手haha@thegalah,这个问题太宽泛了,我回答不了。有很多方法可以做到这一点,你的应用程序可以采用很多结构。根视图控制器通常是容器控制器之一,如导航控制器、选项卡栏控制器或拆分视图控制器。我建议您阅读“iOS视图控制器编程指南”,以及“iOS视图控制器目录”,以便更好地了解各种可能性。我认为我已经找到了更改视图的正确方法。它并没有真正改变视图,但确实有效。基本上,我将初始化的viewcontroller添加为childviewcontroller,并使用以下命令将viewcontroller视图添加为子视图:
UIViewController*vc=[[View2 alloc]init];[self-addChildViewController:vc];[self.view addSubview:vc.view]