Ios 将子视图控制器添加到当前视图控制器
我正在尝试使用以下代码在代码中将子视图控制器添加到故事板中的当前视图控制器:Ios 将子视图控制器添加到当前视图控制器,ios,objective-c,uinavigationcontroller,Ios,Objective C,Uinavigationcontroller,我正在尝试使用以下代码在代码中将子视图控制器添加到故事板中的当前视图控制器: UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle: nil]; LogInTutorialViewController *lvc = [[LogInTutorialViewController alloc] init]; lvc = (LogInTutorialViewController *)[storyboard i
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];
}
该视图似乎至少显示在模拟器上,但在控制台中,我发现了很多错误:
<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.
:CGContextSaveGState:无效的上下文0x0。这是一个严重的错误。此应用程序或其使用的库正在使用无效的上下文,从而导致系统稳定性和可靠性的整体降级。此通知是出于礼貌:请解决此问题。这将成为即将进行的更新中的致命错误。
以及相同的描述但不同的错误:
CGContextSetLineWidth、CGContextSetLineJoin、CGContextSetLineCap、CGContextSetMiterLimit、CGContextSetFlatness、CGContextAddPath、CGContextDrawPath、CGContextRestoreGState
所有这些错误都会记录两次
有人知道我做错了什么吗
我也读了一些帖子,在一些帖子中,有人建议在传递数据之前alloc和init视图控制器,我也尝试了,但没有任何运气。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];
有关更多信息,请查看此项。- 在Interface Builder中配置容器
- 将子视图控制器添加到内容中
addChildViewController:
方法。
此方法告诉UIKit您的容器视图控制器现在正在管理子视图控制器的视图- (void)displayContentController:(UIViewController *)content {
[self addChildViewController:content];
content.view.frame = [self frameForContentController];
[self.view addSubview:self.currentClientView];
[content didMoveToParentViewController:self];
}
Swift:
func displayContentController(_ content: UIViewController?) {
if let content = content {
addChild(content)
}
content?.view.frame = frameForContentController()
view.addSubview(currentClientView)
content?.didMove(toParent: self)
}
关于同一示例的更多详细说明,请参见Swift中的解决方案(撰写本文时为Swift 4): 注:
- 故事板名称为“Main”
- 情节提要中的视图控制器标识符名为“登录”
- 这将使用故事板创建加载视图控制器,但同样可以通过编程方式完成。在尝试访问视图的框架之前,请确保视图已加载到内存中,否则会发生崩溃(执行类似于以模态方式呈现视图控制器的操作)
UIViewController
extension UIViewController {
func addChildViewControllerWithView(_ childViewController: UIViewController, toView view: UIView? = nil) {
let view: UIView = view ?? self.view
childViewController.removeFromParent()
childViewController.willMove(toParent: self)
addChild(childViewController)
childViewController.didMove(toParent: self)
childViewController.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(childViewController.view)
view.addConstraints([
NSLayoutConstraint(item: childViewController.view!, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0),
NSLayoutConstraint(item: childViewController.view!, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0),
NSLayoutConstraint(item: childViewController.view!, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0),
NSLayoutConstraint(item: childViewController.view!, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: 0)
])
view.layoutIfNeeded()
}
func removeChildViewController(_ childViewController: UIViewController) {
childViewController.removeFromParent()
childViewController.willMove(toParent: nil)
childViewController.removeFromParent()
childViewController.didMove(toParent: nil)
childViewController.view.removeFromSuperview()
view.layoutIfNeeded()
}
}
每当您想在
viewdiload()
方法中添加UIViewController
时,您需要调用addChildViewControllerWithView(someVC)
当我到达以下行时,所有错误都会被记录下来:[content.view setFrame:CGRectMake(0,0[UIScreen mainScreen].bounds.size.width[UIScreen mainScreen].bounds.size.height];尝试先添加子视图,然后将其设置为框架。现在我怀疑问题与子视图控制器视图中的内容有关,而不是父子关系。尝试了下一个代码:[self addChildViewController:content];[self.view addSubview:content.view];[content-didMoveToParentViewController:self];[content.view setFrame:CGRectMake(0,0[UIScreen mainScreen].bounds.size.width[UIScreen mainScreen].bounds.size.height)];我现在仍然在didMoveToParent行上记录错误LogintAutorialViewController视图中有什么?看起来它有一些绘图问题。我发布的代码和你回答的代码有什么区别?你的代码行和我的代码行的顺序什么是currentClientView?那么你现在做的是:[self.view addSubview:self.view]这是错误的还是你在做[self.view addSubview:content.view]这和我的代码是一样的……你不需要这一行LogInTutorialViewController*lvc=[[LogInTutorialViewController alloc]init]代码>,因为您是从故事板实例化的。对于下面的错误检查答案,我相信您的顺序是不正确的。是的,我知道,但我只是尝试了一下,作为一个帖子的提示。让我感到不舒服的部分是必须明确地将原点设置为零。这个[self.loginView.view setFrame:self.contentView.frame]
不能在视图中为我正确设置它,因为我的contentView
有一个UINavigationBar
所以contentView.frame.origin.y
被按下了self.loginView
。谢谢这个答案有15票以上,被接受的答案有13票以上。所以我认为这个答案一定是一个公认的答案谢谢,这个解决方案在swift 4中非常有效
extension UIViewController {
func addChildViewControllerWithView(_ childViewController: UIViewController, toView view: UIView? = nil) {
let view: UIView = view ?? self.view
childViewController.removeFromParent()
childViewController.willMove(toParent: self)
addChild(childViewController)
childViewController.didMove(toParent: self)
childViewController.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(childViewController.view)
view.addConstraints([
NSLayoutConstraint(item: childViewController.view!, attribute: .top, relatedBy: .equal, toItem: view, attribute: .top, multiplier: 1, constant: 0),
NSLayoutConstraint(item: childViewController.view!, attribute: .bottom, relatedBy: .equal, toItem: view, attribute: .bottom, multiplier: 1, constant: 0),
NSLayoutConstraint(item: childViewController.view!, attribute: .leading, relatedBy: .equal, toItem: view, attribute: .leading, multiplier: 1, constant: 0),
NSLayoutConstraint(item: childViewController.view!, attribute: .trailing, relatedBy: .equal, toItem: view, attribute: .trailing, multiplier: 1, constant: 0)
])
view.layoutIfNeeded()
}
func removeChildViewController(_ childViewController: UIViewController) {
childViewController.removeFromParent()
childViewController.willMove(toParent: nil)
childViewController.removeFromParent()
childViewController.didMove(toParent: nil)
childViewController.view.removeFromSuperview()
view.layoutIfNeeded()
}
}