Ich habe eine UIViewController
, die ich aus einem anderen View-Controller heraus lade und dann deren Ansicht zu einer UIScrollView
hinzufüge.
self.statisticsController = [self.storyboard instantiateViewControllerWithIdentifier:@"StatisticsViewController"];
self.statisticsController.match = self.match;
[self.scrollView addSubview:self.statisticsController.view];
Ich habe Haltepunkte in den Controller für die Statistikansicht gesetzt und viewDidLoad
wird aufgerufen, viewWillAppear
jedoch nicht.
Liegt es daran, dass ich es nicht in die Hierarchie schiebe oder so?
Sie sollten statisticsController
als untergeordneten Ansichtscontroller des Controllers hinzufügen, zu dessen Ansicht Sie ihn hinzufügen.
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];
Ich bin nicht sicher, ob viewDidAppear
aufgerufen wird, aber Sie können didMoveToParentViewController:
im untergeordneten Controller überschreiben, und das wird aufgerufen. Sie können also jeden Code eingeben, den Sie in viewDidAppear
eingegeben hätten.
Ich stoße -viewWillAppear:
nicht erneut auf ein Problem Nach dem googeln bin ich hierher gekommen. Ich habe einige Tests durchgeführt und herausgefunden, dass die Aufrufreihenfolge von -addSubview
und -addChildViewController:
wichtig ist.
Fall 1. löst -viewWillAppear:
des Controllers aus, aber Fall 2, es WON'T rufen -viewWillAppear:
auf.
Fall 1:
controller?.willMoveToParentViewController(self)
// Call addSubview first
self.scrollView.addSubview(controller!.view)
self.addChildViewController(controller!)
controller!.didMoveToParentViewController(self)
Fall 2:
controller?.willMoveToParentViewController(self)
// Call adChildViewController first
self.addChildViewController(controller!)
self.scrollView.addSubview(controller!.view)
controller!.didMoveToParentViewController(self)
Standardmäßig werden Erscheinungsrückrufe automatisch an untergeordnete Elemente weitergeleitet .. __, die mit der shouldAutomaticallyForwardAppearanceMethods - Eigenschaft festgelegt werden. Überprüfen Sie den Wert dieser Eigenschaft. Wenn es NO ist und Ihr untergeordneter viewController beim Erscheinungsbild des Containers richtig angezeigt werden soll, sollten Sie child mit den folgenden Methoden in der Controller-Lebenszyklus-Implementierung des Containers benachrichtigen:
- (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];
}
Anpassen des Aussehens und des Rotationsrückrufverhaltens
Mein Problem behoben Ich hoffe es wäre hilfreich.
Wie in einer anderen Antwort erwähnt, ruft der übergeordnete View-Controller möglicherweise nicht viewWillAppear
usw. auf, wenn shouldAutomaticallyForwardAppearanceMethods
auf false
eingestellt ist. UINavigationController
und UITabBarController
sind dafür bekannt. In diesem Fall müssen Sie beginAppearanceTransition(_ isAppearing: Bool, animated: Bool)
im untergeordneten View-Controller aufrufen, wobei isAppearing
auf true
gesetzt ist, wenn die Ansicht angezeigt wird, und umgekehrt.
Sie müssen diese Anrufe an geeigneten Stellen in Ihrem Code durchführen, normalerweise, wenn Sie Ihren untergeordneten View-Controller hinzufügen und entfernen.
Vergessen Sie nicht, endAppearanceTransition
in Ihrem untergeordneten Ansichtscontroller aufzurufen, wenn der benutzerdefinierte Übergang beendet ist. Andernfalls werden viewDidAppear
und viewDidDisappear
nicht aufgerufen.
Pro Apple ( https://developer.Apple.com/library/content/featuredarticles/ViewControllerPGforiPhoneOS/ImplementingaContainerViewController.html ) lautet die korrekte Reihenfolge der API-Aufrufe zum Hinzufügen eines untergeordneten View-Controllers:
[self addChildViewController:childVC];
[self.view addSubview:childVC.view];
[childVC didMoveToParentViewController:self];
Ich hatte aber immer noch das Problem, dass viewWillAppear beim Kind VC nicht immer wieder aufgerufen wurde. Mein Problem war, dass es eine Race-Bedingung gab, die dazu führen konnte, dass der Code oben ausgeführt wurde , bevor viewDidAppear in der Containeransicht aufgerufen wurde. Durch die Sicherstellung, dass viewDidAppear bereits aufgerufen wurde (oder die Hinzufügung des Kindes VC erst verschoben wurde), wurde es für mich gelöst.
Die vorherigen Antworten sind richtig, aber wenn es jemandem hilft - wenn Sie loadView
im untergeordneten View-Controller überschreiben, wird keine der anderen UIViewController-Methoden aufgerufen.
Ich brauchte einige Zeit, um zu verstehen, warum mein Code nicht richtig lief, bis ich merkte, dass ich versehentlich loadView
anstelle von viewDidLoad
überschrieben hatte.
In meinem Fall habe ich festgestellt, dass eine viewWillAppear:
-Methode in meiner UINavigationController
-Klasse falsch geschrieben wurde:
override func viewWillAppear(_ animated: Bool) {
super.viewWillDisappear(animated)
// other stuff
}
Beachten Sie, dass ich anstelle von super.viewWillAppear(animated)
super.viewWillDisappear(animated)
geschrieben habe.
Dies führte dazu, dass alle UIViewController
s, die sich in dieser UINavigationController
befanden, die viewWillAppear:
-Methode nicht aufgerufen haben.
Hoffe das hilft jemandem bei einem ähnlichen Problem.