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
被调用但是 viewWillAppear
在 A 中都被调用和 B
您有 3 个曲目可供选择(实际上您有更多曲目,例如使用委托和通知,但这太糟糕了)
- 坚持这个版本,但它不可靠。
- 继续使用故事板,但使用 backCtoA 按钮连接 VC C 中的 A,因此它总是循环但每次都会重新加载。不好但还可以。
- 最后,正确的解决方案是移动到导航控制器(顺便说一句。如果需要,您可以隐藏导航栏)并拥有 VCs Stack,这样您就可以轻松使用 popToViewController
这应该是你的设计:
控制器 A -> 到导航控制器的模态转场(控制器 B 是根视图控制器) -> 将转场推送到控制器 C。
所以如果你想从 C 到 B,你就做一个 pop。
当您想从 B 到 A 或从 C 到 A 时,请执行 dismiss。
我有个小问题。 我正在使用导航控制器中的视图控制器开发一个简单的应用程序,如下所示: 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
被调用但是 viewWillAppear
在 A 中都被调用和 B
您有 3 个曲目可供选择(实际上您有更多曲目,例如使用委托和通知,但这太糟糕了)
- 坚持这个版本,但它不可靠。
- 继续使用故事板,但使用 backCtoA 按钮连接 VC C 中的 A,因此它总是循环但每次都会重新加载。不好但还可以。
- 最后,正确的解决方案是移动到导航控制器(顺便说一句。如果需要,您可以隐藏导航栏)并拥有 VCs Stack,这样您就可以轻松使用 popToViewController
这应该是你的设计:
控制器 A -> 到导航控制器的模态转场(控制器 B 是根视图控制器) -> 将转场推送到控制器 C。
所以如果你想从 C 到 B,你就做一个 pop。
当您想从 B 到 A 或从 C 到 A 时,请执行 dismiss。