如何确定UINavigationControllers中的先前visibleViewController?

gro*_*hog 4 iphone cocoa-touch objective-c

我正在导航视图层次结构的上下文中切换视图,并且我希望能够在切换时确定在新视图下推送的先前视图是什么.

我在UINavigationControllerDelegate中尝试这个:

(void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
{
    NSLog( @"Switching from %@ to %@", 
        NSStringFromClass( [[navigationController visibleViewController] class] ),
        NSStringFromClass( [viewController class] )
    );
}
Run Code Online (Sandbox Code Playgroud)

我明白了:

2009-08-05 20:05:21.274 App Name [85913:20b]从ManagementScreen切换到ManagementScreen

不幸的是,似乎在调用"will"之前,它已经在UINavigationController的状态中被换出,这样传入的viewController总是与UINavigationController上的visibleViewController相同(以及topViewController属性,这里没有演示,但我试过了它用相同的代码).

我想避免扩展导航视图控制器,老实说,虽然我可以轻松地在委托上放置一个属性 - 但是我想知道在现有框架内是否可以实现这种行为(似乎应该在它发生之前调用发生在之后,但似乎导航控制器的状态在之前被修改过).

谢谢!

Dan*_*sby 5

我不认为使用UINavigationControllerDelegate的答案是有效的,因为正如问题所指出的那样,在调用委托时,将要显示的视图控制器已经是navigationController.topViewController和navigationController.visibleViewController的值.

相反,使用观察者.

步骤1.设置观察者以监视UINavigationControllerWillShowViewController通知:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(viewControllerChange:) name:@"UINavigationControllerWillShowViewControllerNotification" object:self.navigationController];
Run Code Online (Sandbox Code Playgroud)

步骤2.创建通知回调(在此示例中称为viewControllerChange)并使用通知userInfo字典中的键来查看上一个和下一个视图控制器:

(void)viewControllerChange:(NSNotification *)notification {
    NSDictionary *userInfo = [notification userInfo];
    NSLog(@"Switching from %@ to %@", [[userInfo objectForKey:@"UINavigationControllerLastVisibleViewController"] class], [[userInfo objectForKey:@"UINavigationControllerNextVisibleViewController"] class]);
}
Run Code Online (Sandbox Code Playgroud)