popToViewController 之后未调用 viewWillAppear

viewWillAppear not called after popToViewController

我有个小问题。 我正在使用导航控制器中的视图控制器开发一个简单的应用程序,如下所示: A->B->C(-> 是模态转场) 视图 A 是根视图控制器,我需要从 C 返回到 A。如果我从 B 调用方法 popToViewController,A 运行 viewWillAppear;如果我从 C(到 A)调用 popToViewController,则不会调用 A 上的 viewWillAppear。 我该如何解决这个问题? (正在处理 Xcode7 和 iOS 9)

ViewController一个

#import "ViewControllerA.h"
#import "ViewControllerB.h"

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

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier] isEqualToString:@"goToB"]) {
       ViewControllerB *b = [segue destinationViewController];
    }
}

ViewController B

#import "ViewControllerB.h"
#import "ViewControllerC.h"

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

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
    if ([[segue identifier] isEqualToString:@"goToC"]) {
       ViewControllerC *c = [segue destinationViewController];
    }
}

- (IBAction)backToAButton:(id)sender {
    [self dismissViewControllerAnimated:NO completion:nil];
}

ViewController C

#import "ViewControllerC.h";

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

    [self setupSceneC];
}


- (IBAction)backToBButton:(id)sender {
    [self dismissViewControllerAnimated:NO completion:nil];
}

- (IBAction)backToAButton:(id)sender {
    [[self parentViewController] dismissViewControllerAnimated:NO completion:nil];
}

如果你实现了下面提供的这两个 CASES 之一,你肯定会得到 viewWillAppear 并确保你写的是正确的 super

-(void)viewWillAppear:(BOOL)animated {
    [super viewWillAppear:animated];
    // Your code goes here
}

案例 1 - 使用导航控制器

如果您想从一个 ViewController 弹出到另一个,您需要将它们全部放在同一个导航堆栈中。这意味着每次你想打开新的视图控制器你需要做这样的事情:

 [self.navigationController pushViewController:nextVC animated:YES];

而不是这样做

[self presentViewController:nextVC animated:YES completion:nil];

之后,如果您已经在同一个导航控制器中拥有所有 VC,您可以使用此代码后退一步(例如从 B 到A、从C到B)

[self.navigationController popViewControllerAnimated:YES];

您可以使用此代码跳转到开头(例如从 C 到 A)

[self.navigationController popToRootViewControllerAnimated:YES];


案例 2 - 普通周期(看起来像您需要的)
这很简单,但您需要更加小心地编写代码。您可以只获取 parent 的 parent 以离开当前 View Controller

[[[自我呈现ViewController] 呈现ViewController] dismissViewControllerAnimated:NO completion:nil];



注意:您不能将导航控制器功能与模态呈现功能一起使用。 Push 是 Pop,Present 是 Dismiss


更新 1

模态转场正在创建嵌套连接(树的一行)。如果关闭 child(current) VC parent VC 正常出现。如果您想跳转到 parent 的 parent,只需关闭 parent,它将关闭所有 child VC。我不知道为什么 popViewControllerAnimated 从 B 到 A 都能正常工作,但你不能那样做。如果您使用模态转场,只需使用 dismiss。永远不要使用 Pop。 Pop 是 Push 的意思。这样做,一切都会正常。

要从 B 返回到 A,请将您的代码更改为:

[self dismissViewControllerAnimated:YES completion:nil];

要从 C 返回到 A,请使用此代码:

[[self parentViewController] dismissViewControllerAnimated:YES completion:nil];

[[self presentingViewController] dismissViewControllerAnimated:YES completion:nil];

更新 2

我发现对于 STORYBOARD segues 我们需要使用这个代码返回

[[[self presentingViewController] presentingViewController] dismissViewControllerAnimated:NO completion:nil];

这段代码从 C 跳转到 A 并且 viewWillAppear 被调用但是 viewWillAppearA 中都被调用和 B

您有 3 个曲目可供选择(实际上您有更多曲目,例如使用委托和通知,但这太糟糕了)

  1. 坚持这个版本,但它不可靠。
  2. 继续使用故事板,但使用 backCtoA 按钮连接 VC C 中的 A,因此它总是循环但每次都会重新加载。不好但还可以。
  3. 最后,正确的解决方案是移动到导航控制器(顺便说一句。如果需要,您可以隐藏导航栏)并拥有 VCs Stack,这样您就可以轻松使用 popToViewController

这应该是你的设计:

控制器 A -> 到导航控制器的模态转场(控制器 B 是根视图控制器) -> 将转场推送到控制器 C。

所以如果你想从 C 到 B,你就做一个 pop。

当您想从 B 到 A 或从 C 到 A 时,请执行 dismiss。