別のView Controller内から読み込んで_UIViewController
にビューを追加するUIScrollView
があります。
self.statisticsController = [self.storyboard instantiateViewControllerWithIdentifier:@"StatisticsViewController"];
self.statisticsController.match = self.match;
[self.scrollView addSubview:self.statisticsController.view];
統計ビューコントローラーにブレークポイントを配置し、viewDidLoad
が呼び出されていますが、viewWillAppear
は呼び出されていません。
それは私がそれを階層などにプッシュしていないからですか?
ビューを追加するコントローラーの子ビューコントローラーとしてstatisticsController
を追加する必要があります。
self.statisticsController = [self.storyboard instantiateViewControllerWithIdentifier:@"StatisticsViewController"];
self.statisticsController.match = self.match;
[self.scrollView addSubview:self.statisticsController.view];
[self addChildViewController:self.statisticsController];
[self.statisticsController didMoveToParentViewController:self];
これによってviewDidAppear
が呼び出されるかどうかはわかりませんが、didMoveToParentViewController:
が子コントローラーで呼び出され、それが呼び出されるため、viewDidAppear
に入れたコードをそこに入れることができます。
-viewWillAppear:
再び問題と呼ばれることはありません。グーグルの後、私はここに来ました。いくつかのテストを行ったところ、-addSubview
および-addChildViewController:
は重要。
ケース1。トリガー-viewWillAppear:
が、コントローラケース2 it WO N'T call -viewWillAppear:
。
事例1:
controller?.willMoveToParentViewController(self)
// Call addSubview first
self.scrollView.addSubview(controller!.view)
self.addChildViewController(controller!)
controller!.didMoveToParentViewController(self)
事例2:
controller?.willMoveToParentViewController(self)
// Call adChildViewController first
self.addChildViewController(controller!)
self.scrollView.addSubview(controller!.view)
controller!.didMoveToParentViewController(self)
デフォルトでは、外観コールバックは自動的に子に転送されます。 shouldAutomaticallyForwardAppearanceMethodsプロパティで決定されます。このプロパティの値をチェックします。[〜#〜] no [〜#〜]で、子のviewControllerがコンテナの外観に正しく表示される場合は、コンテナのコントローラライフサイクル実装で次のメソッドを使用して子に通知する必要があります。
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
for (UIViewController *child in self.childViewControllers) {
[child beginAppearanceTransition:YES animated:animated];
}
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
[self.child endAppearanceTransition];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
for (UIViewController *child in self.childViewControllers) {
[child beginAppearanceTransition:NO animated:animated];
}
}
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
[self.child endAppearanceTransition];
}
私の問題を修正しました!それが役に立てば幸いです。
別の回答で述べたように、viewWillAppear
がshouldAutomaticallyForwardAppearanceMethods
に設定されている場合、親View Controllerはfalse
などを呼び出さない場合があります。 UINavigationController
とUITabBarController
がそうすることが知られています。この場合、ビューが表示されるときにisAppearing
をtrue
に設定して、子View ControllerでbeginAppearanceTransition(_ isAppearing: Bool, animated: Bool)
を呼び出す必要があります。
通常、子View Controllerを追加および削除するときに、コード内の適切な場所にこれらの呼び出しを配置する必要があります。
カスタムトランジションが終了したら、子View ControllerでendAppearanceTransition
を呼び出すことを忘れないでください。そうでない場合、viewDidAppear
とviewDidDisappear
は呼び出されません。
Per Apple( https://developer.Apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html )、追加するAPI呼び出しの正しい順序子View Controllerは次のとおりです。
[self addChildViewController:childVC];
[self.view addSubview:childVC.view];
[childVC didMoveToParentViewController:self];
しかし、子供のviewWillAppear VCが時々呼び出されないという問題がありました。私の問題は、上記のコードが実行される原因となる競合状態があったことですbeforeコンテナView ControllerのviewDidAppearが呼び出されました。viewDidAppearが既に呼び出されていることを確認します(または、子の追加を延期しますVCだった)私のためにそれを解決しました。
前の答えは正しいですが、誰かに役立つ場合-子View ControllerでloadView
をオーバーライドすると、他のUIViewControllerメソッドは呼び出されません。
誤ってloadView
の代わりにviewDidLoad
をオーバーライドしたことに気付くまで、コードが正しく実行されなかった理由を理解するためにしばらく時間がかかりました。
私の場合、ベースUINavigationController
クラスの_viewWillAppear:
_メソッドを誤って書き換えていることがわかりました。
_override func viewWillAppear(_ animated: Bool) {
super.viewWillDisappear(animated)
// other stuff
}
_
super.viewWillAppear(animated)
を呼び出す代わりに、super.viewWillDisappear(animated)
を作成したことに注意してください。
そのため、このUIViewController
内にあるUINavigationController
のすべてが_viewWillAppear:
_メソッドを呼び出していませんでした。
同様の問題で誰かを助けることを願っています。