不幸的是,isMovingToParentViewController无法在子视图控制器中工作。在我的情况下,它总是在viewWillDisappear中返回NO。
重现步骤:
UINavigationController
viewWillDisappear:
中编写测试代码。viewWillDisappear:
方法中isMovingToParentViewController始终是NO
。问题
如果它是儿童视图控制器,有没有办法知道导航方向丢弃?
或者在实现容器视图控制器时我需要注意什么?
答案 0 :(得分:1)
原始答案的基础(下文)仍然有效。我们会在容器视图控制器中使用isMovingToParentViewController
和isMovingFromParentViewController
来确定推送/弹出,然后通知嵌入式(或儿童)查看控制器。
为了使其尽可能灵活(可能有许多嵌入的UIViewController
子类)我已经定义了EmbeddableViewController
类别。
@protocol EmbeddableViewController <NSObject>
- (void)embeddable_isBeingPushedOntoNavigationController:(UINavigationController *)navigationController;
- (void)embeddable_isBeingPoppedOffNavigationController:(UINavigationController *)navigationController;
@end
每个嵌入式/子视图控制器都需要符合此协议:
@interface EmbeddedViewController : UIViewController <EmbeddableViewController>
@end
@implementation EmbeddedViewController
- (void)embeddable_isBeingPushedOntoNavigationController:(UINavigationController *)navigationController {
// do whatever
}
- (void)embeddable_isBeingPoppedOffNavigationController:(UINavigationController *)navigationController {
// do whatever
}
@end
容器视图控制器需要在prepareForSegue:sender:
方法中获取对嵌入式视图控制器的引用,检测推/弹导航并通知嵌入式视图控制器:
@interface OuterViewController ()
// Keep a reference to the embedded controller
@property (nonatomic, strong) UIViewController<EmbeddableViewController>* embeddedViewController;
@end
@implementation OuterViewController
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self notifyEmbeddedViewControllerOfNavigation];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self notifyEmbeddedViewControllerOfNavigation];
}
- (void)notifyEmbeddedViewControllerOfNavigation {
if ([self isMovingToParentViewController]) {
[self.embeddedViewController embeddable_isBeingPushedOntoNavigationController:self.navigationController];
} else if ([self isMovingFromParentViewController]) {
[self.embeddedViewController embeddable_isBeingPoppedOffNavigationController:self.navigationController];
}
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
[super prepareForSegue:segue sender:sender];
// Assuming the storyboard has set the embed segue's identifier to "Embedded"
if ([segue.identifier isEqualToString:@"Embedded"]) {
self.embeddedViewController = segue.destinationViewController;
}
}
@end
来自updated sample project的控制台输出:
2015-08-12 09:51:41.900 stack2[2263:569042] OuterViewController Is being pushed
2015-08-12 09:51:41.901 stack2[2263:569042] EmbeddedViewController -[EmbeddedViewController embeddable_isBeingPushedOntoNavigationController:]
2015-08-12 09:51:42.777 stack2[2263:569042] OuterViewController Is being pushed
2015-08-12 09:51:42.778 stack2[2263:569042] EmbeddedViewController -[EmbeddedViewController embeddable_isBeingPushedOntoNavigationController:]
2015-08-12 09:51:44.037 stack2[2263:569042] OuterViewController Is being pushed
2015-08-12 09:51:44.037 stack2[2263:569042] EmbeddedViewController -[EmbeddedViewController embeddable_isBeingPushedOntoNavigationController:]
2015-08-12 09:51:44.777 stack2[2263:569042] OuterViewController Is being popped
2015-08-12 09:51:44.777 stack2[2263:569042] EmbeddedViewController -[EmbeddedViewController embeddable_isBeingPoppedOffNavigationController:]
2015-08-12 09:51:45.409 stack2[2263:569042] OuterViewController Is being popped
2015-08-12 09:51:45.410 stack2[2263:569042] EmbeddedViewController -[EmbeddedViewController embeddable_isBeingPoppedOffNavigationController:]
2015-08-12 09:51:46.174 stack2[2263:569042] OuterViewController Is being popped
2015-08-12 09:51:46.174 stack2[2263:569042] EmbeddedViewController -[EmbeddedViewController embeddable_isBeingPoppedOffNavigationController:]
来自isMovingToParentViewController
的文档:
此方法仅在从内部调用时返回YES viewWillAppear:和viewDidAppear:methods。
isMovingFromParentViewController
:
此方法仅在从内部调用时返回YES viewWillDisappear:和viewDidDisappear:methods。
有了这些知识,子视图控制器可以确定导航是推送还是流行...
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
[self checkNavigationDirection];
}
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
[self checkNavigationDirection];
}
- (void)checkNavigationDirection {
if ([self isMovingToParentViewController]) {
NSLog(@"%p Is being pushed", self);
}
else if ([self isMovingFromParentViewController]) {
NSLog(@"%p Is being popped", self);
}
}
在按下3个视图控制器后,(样本)控制台输出结果,然后弹出3个视图控制器:
2015-08-12 09:10:56.296 stack2[1487:358827] 0x7fff09e0bba0 Is being pushed
2015-08-12 09:10:57.420 stack2[1487:358827] 0x7fff09f6b980 Is being pushed
2015-08-12 09:10:58.365 stack2[1487:358827] 0x7fff09c2f800 Is being pushed
2015-08-12 09:10:59.167 stack2[1487:358827] 0x7fff09c2f800 Is being popped
2015-08-12 09:10:59.782 stack2[1487:358827] 0x7fff09f6b980 Is being popped
2015-08-12 09:11:00.311 stack2[1487:358827] 0x7fff09e0bba0 Is being popped
随意下载sample project。
答案 1 :(得分:0)
来自the docs for isMovingFromParentViewController
:
此方法仅在从内部调用时返回
YES
viewWillDisappear:
和viewDidDisappear:
方法。
isMovingToParentViewController
:
此方法仅在从内部调用时返回
YES
viewWillAppear:
和viewDidAppear:
方法。
因此,如果它适合在此处使用此信息,请将代码移至这些视图外观方法。
如果没有,您将不得不自己实施某种逻辑。这可能涉及容器控制器将Bool
传递给子视图控制器以进行每次转换,或者在容器控制器上具有返回所需信息的委托方法。