【问题标题】:viewDidLoad not called when modifying navigation stack修改导航堆栈时未调用 viewDidLoad
【发布时间】:2014-11-12 15:35:17
【问题描述】:

我正在从导航堆栈中删除所有视图,然后创建一个新控制器(从情节提要)并将其添加为堆栈中的唯一控制器。问题是 viewDidLoad 在实例化新控制器时永远不会被调用(用断点检查)。任何想法为什么会发生这种情况?代码如下。

[self.collectionView.collectionViewLayout invalidateLayout];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
PFGridPageViewController *nc = [storyboard instantiateViewControllerWithIdentifier:@"GridPageVC"];
[self.navigationController setViewControllers:nil];
NSArray *new = [[NSArray alloc] initWithObjects:nc, nil];
[self.navigationController setViewControllers:new];

临时解决方案

正如您在接受的答案中与 Ian 的讨论中看到的那样,修改导航堆栈是一个坏主意。当我在做更好的事情时,我想出了一个临时解决方案。基本上我使用 popToRoot 和 pushVC 然后修改堆栈一次以删除索引 0 处的 VC。

[self.navigationController popToRootViewControllerAnimated:NO];
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
PFGridPageViewController *nc = [storyboard instantiateViewControllerWithIdentifier:@"GridPageVC"];
[self.navigationController pushViewController:nc animated:NO];
NSMutableArray *controllers = [NSMutableArray arrayWithArray:self.navigationController.viewControllers];
[controllers removeObjectAtIndex:0];
[self.navigationController setViewControllers:controllers];

【问题讨论】:

  • 代码中的问题是将 viewControllers 设置为 nil。没有必要这样做。如果您只是将一个新数组分配给导航控制器的 viewControllers 属性,它就可以正常工作。我认为您甚至不应该看到您的新视图控制器(是吗?),因为当您将 viewControllers 设置为 nil 时,self.navigationController 将变为 null。
  • @rdelmar 我不知道,谢谢。
  • 您也可以使用 setViewControllers:animated: 让它看起来像您将 nc 推入堆栈,即使您重置了数组。
  • 通过重置 viewControllers 数组来修改堆栈没有任何问题,只要您正确执行即可(查看 Apple 在方法的引用中所说的 setViewControllers:animated:)。这不是一个坏主意。

标签: ios objective-c


【解决方案1】:

viewDidLoad 仅在您访问 UIViewController.view 属性时调用。这似乎是一种非常规的 [self.navigationController pushViewController:nc animated:NO] 方式。

如果您确定自己的实现(我不确定),只需在某处添加此行,它将为您调用 viewDidLoad

[nc view];

【讨论】:

  • 我同意这个实现很奇怪,但这是我能找到的完成我需要的最好方法。它只在一个地方使用,我在其他任何地方都使用传统导航。感谢您的回答,现在正在调用 viewDidLoad。
  • 知道如何让其他生命周期方法(viewWillAppear 等)工作吗?即使有您的添加,它们也不会被调用。
  • viewWillAppear 这样的生命周期方法被传播到所有子视图控制器;我想你可以用[self.navigationController addChildViewController:nc] 来完成这个,但我仍然不喜欢这个实现。通过使用setViewControllers:nil,您将导致现有堆栈也无法获得拆除生命周期事件(viewWillDisappear 等)。您确定不能只使用popViewControllerAnimated:pushViewController:animated:
  • “通过使用 setViewControllers:nil,你会导致你现有的堆栈也没有得到拆卸生命周期事件”我没有意识到这一点!基本上我有一个带有许多视图控制器的导航控制器。当放置一个按钮时,我需要删除所有这些视图控制器并用一个新的替换它们。
  • popToRootViewControllerAnimated: 后跟pushViewController:animated:
猜你喜欢
  • 1970-01-01
  • 2011-03-16
  • 1970-01-01
  • 2013-02-19
  • 1970-01-01
  • 1970-01-01
  • 2019-10-08
  • 2019-03-08
  • 2023-04-03
相关资源
最近更新 更多