将子视图控制器添加到当前视图控制器
我试图通过使用下一个代码添加一个子视图控制器的代码,从故事板到当前的视图控制器:
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil]; LogInTutorialViewController *lvc = [[LogInTutorialViewController alloc] init]; lvc = (LogInTutorialViewController *)[storyboard instantiateViewControllerWithIdentifier:@"LogInTutorialViewControllerID"]; [self displayContentController:lvc]; - (void) displayContentController: (LogInTutorialViewController*) content; { //add as childViewController [self addChildViewController:content]; [content didMoveToParentViewController:self]; [content.view setFrame:CGRectMake(0, 0, [UIScreen mainScreen].bounds.size.width, [UIScreen mainScreen].bounds.size.height)]; [self.view addSubview:content.view]; }
视图似乎至less在模拟器上显示,但在控制台我得到很多或错误:
<Error>: CGContextSaveGState: invalid context 0x0. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.
也是相同的描述,但不同的错误:
CGContextSetLineWidth,CGContextSetLineJoin,CGContextSetLineCap,CGContextSetMiterLimit,CGContextSetFlatness,CGContextAddPath,CGContextDrawPath,CGContextRestoreGState
所有这些错误都logging了两次。
有谁知道我在做什么错?
我也读了几个post,并在一些build议分配和初始化视图控制器之前传递的数据,我也试过,没有任何运气。
didMoveToParentViewController必须是最后一个。
为什么你不试试这个代码添加视图,我认为这是简单和容易..
self.loginView = [self.storyboard instantiateViewControllerWithIdentifier:@"LOGIN"]; [self addChildViewController:self.loginView]; [self.loginView.view setFrame:CGRectMake(0.0f, 0.0f, self.contentView.frame.size.width, self.contentView.frame.size.height)]; [self.contentView addSubview:self.loginView.view]; [self.loginView didMoveToParentViewController:self];
欲了解更多信息,请查看此链接 。
- 在界面构build器中configuration容器。
要在devise时创build父子容器关系,请将容器视图对象添加到故事板场景中,如下图所示。 容器视图对象是代表子视图控制器内容的占位符对象。 使用该视图来调整和定位与容器中其他视图相关的子视图。
当您使用一个或多个容器视图加载视图控制器时,Interface Builder还会加载与这些视图关联的子视图控制器。 孩子必须与父母同时实例化,以便build立适当的亲子关系。
如果您不使用Interface Builder设置父 – 子容器关系,则必须通过将每个子项添加到容器视图控制器来以编程方式创build这些关系,如将子视图控制器添加到您的内容中所述。
- 将子视图控制器添加到您的内容。
要以编程方式将子视图控制器合并到内容中,请执行以下操作,在相关的视图控制器之间创build父子关系:
- 调用容器视图控制器的
addChildViewController:
方法。 这个方法告诉UIKit你的容器视图控制器现在正在pipe理子视图控制器的视图。 - 将孩子的根视图添加到容器的视图层次结构中。 一定要记住设置孩子框架的大小和位置,作为这个过程的一部分。
- 添加任何约束来pipe理子视图的大小和位置。
- 调用子视图控制器的didMoveToParentViewController:方法。
这是这个代码。
- (void)displayContentController:(UIViewController *)content { [self addChildViewController:content]; content.view.frame = [self frameForContentController]; [self.view addSubview:self.currentClientView]; [content didMoveToParentViewController:self]; }
在Apple开发者编程指南中给出了相同示例的更多细节解释。
Swift中的解决scheme (撰写本文时的Swift 4):
//load the view controller and add as child storyboard = UIStoryboard(name: "Main", bundle: Bundle.main) loginVC = storyboard.instantiateViewController(withIdentifier: "LOGIN") addChildViewController(loginVC) //make sure that the child view controller's view is the right size loginVC.view.frame = contentView.bounds contentView.addSubview(loginVC.view) //you must call this at the end per Apple's documentation loginVC.didMove(toParentViewController: self)
笔记:
- 故事板名称是“主”。
- 故事板中的视图控制器标识符被命名为“LOGIN”。
- 这使用一个故事板来创build加载视图控制器,但同样可以通过编程来完成。 只要确保在尝试访问视图的框架之前将视图加载到内存中,或者会发生崩溃(以模态方式呈现视图控制器)。