iOS如何将viewDidAppear事件传递给子视图控制器?

9
我正在将一个子视图控制器添加到父视图控制器中,除了没有触发子视图控制器的通常回调之外,一切都如预期一样。例如,viewWillAppear(animated)从未被调用。我研究了一下,发现可能是因为在将子视图控制器添加到父视图之前和之后,我没有调用willMoveToParentViewController和didMoveToParentViewController。不幸的是,修复这个问题没有任何改变。有谁知道我该如何连接它,以便当我执行addChildViewController和removeChildViewController时,正常的回调被触发?在添加childViewController之后,我还将其视图作为父视图控制器的视图的子视图添加。在addChildViewController和addSubview的任何一点上,都不会调用子视图控制器的viewWillAppear(animated)等方法...
7个回答

12

viewWillAppearviewDIdAppear是在将您的ViewControler视图添加到视图层次结构中时自动调用的。

viewWillDisappearviewDidDisappear是当您从视图层次结构中移除ViewControler视图时自动调用的。

如果在显示主视图控制器之前添加子控制器视图,可能不会调用这些方法,因此您的主视图本身不在视图层次结构中?

当您的主视图控制器出现或消失时,应在相应的方法中为子级调用这些方法。


8

我不确定这是否适用于您的情况,但请尝试手动向您的子元素发送外观回调方法进行实验。

从苹果的视图控制器容器 文档 中可以看到:

然而,有时默认行为可能会按照不合理的顺序发送这些事件到您的容器中。例如,如果多个子元素同时更改其视图状态,则可能希望 consolideate 更改,以便外观回调在更合理的顺序下同时发生。要做到这一点,您需要修改容器类以接管外观或旋转回调的责任。

它建议手动将外观回调转发给您的子元素,以获得更精细的控制:

// From the container view controller
- (BOOL) shouldAutomaticallyForwardAppearanceMethods
{
    return NO;
}

-(void) viewWillAppear:(BOOL)animated
{
    [self.child beginAppearanceTransition: YES animated: animated];
}

-(void) viewDidAppear:(BOOL)animated
{
    [self.child endAppearanceTransition];
}

-(void) viewWillDisappear:(BOOL)animated
{
    [self.child beginAppearanceTransition: NO animated: animated];
}

-(void) viewDidDisappear:(BOOL)animated
{
    [self.child endAppearanceTransition];
}

8
尝试这个:

试试这个:

childController.willMoveToParentViewController(self)
childController.beginAppearanceTransition(true, animated: true)

添加到您的视图控制器后


1
请确保在动画过渡结束后调用childController.endAppearanceTransition(),否则viewDidAppear方法将不会被调用! - David

4

我刚刚尝试在父视图控制器的viewDidLoad中执行以下操作,似乎可以正常工作。

ChildExperimentViewController *child = [[ChildExperimentViewController alloc]init];
[self addChildViewController:child];
[self.view addSubview:child.view];
[child didMoveToParentViewController:self];

0
let vc = ChildVC.init()
vc.frame = self.view.bounds
self.addChildViewController(vc)
self.view.addSubview(vc.view)
vc.willMove(toParentViewController: self)
vc.didMove(toParentViewController: self)

0

Chourobin answer 在 Swift 中:

override var shouldAutomaticallyForwardAppearanceMethods: Bool {
    return false
}

override func viewWillAppear(_ animated: Bool) {
    self.childViewControllers[self.segmentView.selectedSegmentIndex].beginAppearanceTransition(true, animated: animated)
}

override func viewDidAppear(_ animated: Bool) {
    self.childViewControllers[self.segmentView.selectedSegmentIndex].endAppearanceTransition()
}

override func viewWillDisappear(_ animated: Bool) {
    self.childViewControllers[self.segmentView.selectedSegmentIndex].beginAppearanceTransition(false, animated: animated)
}

override func viewDidDisappear(_ animated: Bool) {
    self.childViewControllers[self.segmentView.selectedSegmentIndex].endAppearanceTransition()
}

补充说明:由于我没有将对子视图控制器的引用作为属性或变量保留,所以更倾向于使用当前选定的段索引来访问它。SegmentView 是第三方UISegmentControl


-4

在父视图控制器中,您可以手动调用子视图控制器的viewWillAppear方法,代码如下:

-(void)viewWillAppear:(BOOL)animated 
{ 
    [super viewWillAppear:animated]; 
    [selectedViewController viewWillAppear:animated];
}

如果您已将navigationController作为childViewController添加,您可以在navigationController的代理中添加以下代码。
-(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated 
{
    [viewController viewWillAppear:animated];
}

如果您已将tabBarController作为子视图控制器添加,您可以在tabBarController的委托和父视图中添加以下代码。
- (void)viewWillAppear:(BOOL)animated { 
    [super viewWillAppear:animated]; 
    [self.tabBarController.selectedViewController viewWillAppear:animated]; 
}

- (void)tabBarController:(UITabBarController *)tabBarController didSelectViewController:(UIViewController *)viewController { 
    [viewController viewWillAppear:NO]; 
}

我不知道这个能否解决你的问题,希望能帮到你。


1
我们永远不应该手动调用viewWillAppear或其他方法。请参考https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/#//apple_ref/occ/instm/UIViewController/beginAppearanceTransition:animated:。 - vivek

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接