次のコードを使用して、ストーリーボードから現在のView Controllerにコードで子View Controllerを追加しようとしています:
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.
また、同じ説明ですが異なるエラー:
CGContextSetLineWidth、CGContextSetLineJoin、CGContextSetLineCap、CGContextSetMiterLimit、CGContextSetFlatness、CGContextAddPath、CGContextDrawPath、CGContextRestoreGState
これらのエラーはすべて2回記録されます。
誰かが私が間違っていることを知っていますか?
また、私はいくつかの投稿を読みましたが、データを渡す前にView Controllerを割り当てて初期化することが提案されたものもありましたが、幸運なくそれを試しました。
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];
詳細については、これを確認してください link 。
設計時に親子コンテナの関係を作成するには、下の画像に示すように、ストーリーボードシーンにコンテナビューオブジェクトを追加します。コンテナビューオブジェクトは、子ビューコントローラのコンテンツを表すプレースホルダーオブジェクトです。そのビューを使用して、コンテナ内の他のビューに対して子のルートビューのサイズと位置を設定します。
1つ以上のコンテナビューを持つView Controllerをロードすると、Interface Builderはそれらのビューに関連付けられた子View Controllerもロードします。適切な親子関係を作成できるように、子は親と同時にインスタンス化する必要があります。
Interface Builderを使用して親子コンテナの関係を設定しない場合は、「子View Controllerをコンテンツに追加する」の説明に従って、各子をコンテナView Controllerに追加して、プログラムでそれらの関係を作成する必要があります。
子View Controllerをプログラムでコンテンツに組み込むには、以下を実行して、関連するView Controllerの間に親子関係を作成します。
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)
}
同じ例の詳細な説明は Apple developer programming guide にあります。
Swiftのソリューション(この記事の執筆時点での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)
ノート: