我需要知道我的视图控制器何时会从导航堆栈中弹出,以便我可以执行操作。
我不能使用-viewWillDisappear,因为当视图控制器由于任何原因(例如新的视图控制器被推到顶部)移出屏幕时会调用它。
我特别需要知道控制器即将自动弹出的时间。
任何想法都会很棒,提前谢谢。
答案 0 :(得分:75)
覆盖显示的VC中的viewWillDisappear
方法,然后检查覆盖中的isMovingFromParentViewController
标志并执行特定逻辑。在我的情况下,我隐藏了导航控制器工具栏。仍然要求你所呈现的VC理解它被推动但不完美。
答案 1 :(得分:24)
尝试在viewWillDisappear:
的自定义子类中覆盖willMoveToParentViewController:
(而不是UIViewController
)。
在容器视图控制器中添加或删除视图控制器之前调用。
- (void)willMoveToParentViewController:(UIViewController *)parent
{
[super willMoveToParentViewController:parent];
if (!parent) {
// `self` is about to get popped.
}
}
答案 2 :(得分:18)
幸运的是,在调用viewWillDisappear方法时,viewController已经从堆栈中删除了,所以我们知道viewController正在弹出,因为它不再位于 self.navigationController.viewControllers < / p>
Swift 4
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let nav = self.navigationController {
let isPopping = !nav.viewControllers.contains(self)
if isPopping {
// popping off nav
} else {
// on nav, not popping off (pushing past, being presented over, etc.)
}
} else {
// not on nav at all
}
}
原始代码
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
if ((self.navigationController) &&
(![self.navigationController.viewControllers containsObject:self])) {
NSLog(@"I've been popped!");
}
}
答案 3 :(得分:12)
这对我有用。
- (void)viewDidDisappear:(BOOL)animated
{
if (self.parentViewController == nil) {
NSLog(@"viewDidDisappear doesn't have parent so it's been popped");
//release stuff here
} else {
NSLog(@"PersonViewController view just hidden");
}
}
答案 4 :(得分:10)
我认为没有明确的消息,但你可以继承UINavigationController并覆盖 - popViewControllerAnimated(尽管我之前没有尝试过这个)。
或者,如果没有对视图控制器的其他引用,你可以添加到它的 - dealloc吗?
答案 5 :(得分:8)
你可以在这里抓住它。
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated {
if (viewController == YourAboutToAppearController) {
// do something
}
}
这将在显示新视图之前触发。没有人感动。我一直用asinine NavigationController做魔法。你可以设置标题和按钮标题,并在那里做任何事情。
答案 6 :(得分:3)
我有同样的问题。我尝试使用viewDisDisappear,但我没有调用函数:((不知道为什么,也许因为我所有的VC都是UITableViewController)。 Alex的建议工作正常,但如果您的导航控制器显示在更多选项卡下,则会失败。在这种情况下,导航控制器的所有VC都将navigationController作为UIMoreNavigationController,而不是您已经创建子类的导航控制器,因此当VC即将弹出时,导航器不会通知您。 最后,我解决了一个UINavigationController类的问题,只需重写 - (UIViewController *)popViewControllerAnimated:(BOOL)动画
- (UIViewController *)popViewControllerAnimated:(BOOL)animated{
NSLog(@"UINavigationController(Magic)");
UIViewController *vc = self.topViewController;
if ([vc respondsToSelector:@selector(viewControllerWillBePopped)]) {
[vc performSelector:@selector(viewControllerWillBePopped)];
}
NSArray *vcs = self.viewControllers;
UIViewController *vcc = [vcs objectAtIndex:[vcs count] - 2];
[self popToViewController:vcc animated:YES];
return vcc;}
对我来说效果很好:D
答案 7 :(得分:2)
我试过了:
- (void) viewWillDisappear:(BOOL)animated {
// If we are disappearing because we were removed from navigation stack
if (self.navigationController == nil) {
// YOUR CODE HERE
}
[super viewWillDisappear:animated];
}
这个想法是在弹出时,视图控制器的navigationController被设置为nil。 因此,如果视图消失,并且它有更长的导航控制器,我总结它被弹出。 (可能在其他情况下不起作用)。
无法保证在弹出时会调用viewWillDisappear,因为文档中没有提到它。当视图是顶视图时,我尝试了它,并且在顶视图下方 - 它在两者中都有效。
祝你好运, 奥德。答案 8 :(得分:1)
你可以使用这个:
if(self.isMovingToParentViewController)
{
NSLog(@"Pushed");
}
else
{
NSLog(@"Popped");
}
答案 9 :(得分:1)
子类.table-responsive
并覆盖UINavigationController
:
popViewController
答案 10 :(得分:0)
也许您可以使用UINavigationBarDelegate的navigationBar:shouldPopItem协议方法。
答案 11 :(得分:0)
尝试在viewwilldisappear中进行此检查 if([self.navigationController.viewControllers indexOfObject:self] == NSNotFound){ //弹出这个视图已经发生了。 }
答案 12 :(得分:0)
有时我还需要防止突然弹出,所以对我来说最好的答案是Orkhan Alikhanov写的。但这没有用,因为未设置委托,所以我制作了最终版本:
import UIKit
class CustomActionsNavigationController: UINavigationController,
UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
interactivePopGestureRecognizer?.delegate = self
}
override func popViewController(animated: Bool) -> UIViewController? {
if let delegate = topViewController as? CustomActionsNavigationControllerDelegate {
guard delegate.shouldPop() else { return nil }
}
return super.popViewController(animated: animated)
}
// important to prevent UI thread from freezing
//
// if popViewController is called by gesture recognizer and prevented by returning nil
// UI will freeze after calling super.popViewController
// so that, in order to solve the problem we should not return nil from popViewController
// we interrupt the call made by gesture recognizer to popViewController through
// returning false on gestureRecognizerShouldBegin
func gestureRecognizerShouldBegin(_ gestureRecognizer: UIGestureRecognizer) -> Bool {
if let delegate = topViewController as? CustomActionsNavigationControllerDelegate {
if !delegate.shouldPop() {
return false
}
}
// This if statement prevents navigation controller to pop when there is only one view controller
if viewControllers.count == 1 {
return false
}
return true
}
}
protocol CustomActionsNavigationControllerDelegate {
func shouldPop() -> Bool
}
更新
我添加了viewControllers.count == 1
的大小写,因为如果堆栈中有一个控制器并且用户做出手势,它将冻结应用程序的UI。
答案 13 :(得分:0)
您可以看到通知:
- (void)viewDidLoad{
[super viewDidLoad];
[NSNotificationCenter.defaultCenter addObserver:self selector:@selector(navigationControllerWillShowViewController:) name:@"UINavigationControllerWillShowViewControllerNotification" object:nil];
}
- (void)navigationControllerDidShowViewController:(NSNotification *)notification{
UIViewController *lastVisible = notification.userInfo[@"UINavigationControllerLastVisibleViewController"];
if(lastVisible == self){
// we are being popped
}
}
答案 14 :(得分:0)
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
const BOOL removingFromParent = ![self.navigationController.viewControllers containsObject:self.parentViewController];
if ( removingFromParent ) {
// cleanup
}
}