当我的视图控制器被从导航堆栈中推出或弹出时,我需要做某些事情,但是不想使用viewillappear / viewdidappear或viewwilldisappear / viewdiddisappear,因为除了推送/弹出视图控制器之外的那些情况。是正确的方法去使用navigationcontroller委托和navigationController:didShowViewController:animated:和navigationController:willShowViewController:animated:?如果没有,最好的方法是什么?
答案 0 :(得分:7)
要了解它何时被推动,您可以使用
UINavigationControllerDelegate
并实施
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
只要将viewcontroller推入导航堆栈,并且每次弹出顶部的viewcontroller,就会触发此方法,从而再次显示它。因此,您必须使用一个标志来确定它是否已经初始化,如果它没有意味着它刚被推送。
要了解它何时被弹出,请使用以下答案:
答案 1 :(得分:6)
您可以尝试在对象推送或从导航控制器堆栈中弹出时调用的UINavigationController委托方法。
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
答案 2 :(得分:2)
这是一个示例,通过覆盖-viewWillAppear:
并通过覆盖-viewWillDisappear:
-(void) viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if (self.isMovingToParentViewController) {
NSLog(@"view controller being pushed");
}
}
-(void) viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if (self.isMovingFromParentViewController) {
NSLog(@"view controller being popped");
}
}
答案 3 :(得分:1)
您始终可以创建UINavigationController的简单子类并包装其超类的方法,以便在调用它们之前设置一个标志:
ActionNavigationController.h
#import <UIKit/UIKit.h>
@interface ActionNavigationController : UINavigationController
@property (nonatomic, readonly) BOOL pushing;
@end
ActionNavigationController.m
#import "ActionNavigationController.h"
@implementation ActionNavigationController
@synthesize pushing = _pushing;
-(void)pushViewController:(UIViewController *)viewController
animated:(BOOL)animated {
_pushing = YES;
[super pushViewController:viewController animated:animated];
}
- (UIViewController *)popViewControllerAnimated:(BOOL)animated {
_pushing = NO;
return [super popViewControllerAnimated:animated];
}
- (NSArray *)popToViewController:(UIViewController *)viewController
animated:(BOOL)animated {
_pushing = NO;
return [super popToViewController:viewController animated:animated];
}
- (NSArray *)popToRootViewControllerAnimated:(BOOL)animated {
_pushing = NO;
return [super popToRootViewControllerAnimated:animated];
}
@end
如果pushing
事件没有发生,NO
将评估为{{1}}事件,预计将从UINavigationControllerDelegate访问此代码。
答案 4 :(得分:1)
小心使用
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
如果用户从边缘向右滑动以弹出视图控制器(而不是实际弹出它),它将调用上面的委托函数但不会调用函数
- (void)navigationController:(UINavigationController *)navigationController
didShowViewController:(UIViewController *)viewController
animated:(BOOL)animated;
答案 5 :(得分:0)
你可以在willShowViewController
中做类似的事情func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
if self.navigationController!.viewControllers.contains(self){
print ("push")
} else {
print ("pop")
}
}
答案 6 :(得分:0)
这些委托函数不能在iOS13设备(与Xcode 11编译)上调用。这是一个错误吗?
答案 7 :(得分:0)
不好的做法是将委托设置为导航控制器层次结构中的某个内容,而不要注意通知:
UINavigationControllerWillShowViewControllerNotification
UINavigationControllerDidShowViewControllerNotification
并且userInfo对象包含“ NextVisible”和“ LastVisible”视图控制器。但是,在外观方法中使用isMoving
可能是最好的方法。