我正在努力寻找一个好的解决方法来解决这个问题。在视图控制器的-viewWillDisappear:
方法中,我需要找到一种方式来确定是因为视图控制器被推到导航控制器的堆栈上,还是因为视图控制器消失了,因为它已经被弹出。
目前,我正在设置标志,例如isShowingChildViewController
,但它变得相当复杂。我认为唯一可以检测它的方法是在-dealloc
方法中。
我正在努力寻找一个好的解决方法来解决这个问题。在视图控制器的-viewWillDisappear:
方法中,我需要找到一种方式来确定是因为视图控制器被推到导航控制器的堆栈上,还是因为视图控制器消失了,因为它已经被弹出。
目前,我正在设置标志,例如isShowingChildViewController
,但它变得相当复杂。我认为唯一可以检测它的方法是在-dealloc
方法中。
- (void)viewWillDisappear:(BOOL)animated {
[super viewWillDisappear:animated];
NSArray *viewControllers = self.navigationController.viewControllers;
if (viewControllers.count > 1 && [viewControllers objectAtIndex:viewControllers.count-2] == self) {
// View is disappearing because a new view controller was pushed onto the stack
NSLog(@"New view controller was pushed");
} else if ([viewControllers indexOfObject:self] == NSNotFound) {
// View is disappearing because it was popped from the stack
NSLog(@"View controller was popped");
}
}
当然,这是可能的,因为在调用viewWillDisappear方法时,UINavigationController的视图控制器堆栈(通过viewControllers属性公开)已经被更新。
我认为最简单的方法是:
- (void)viewWillDisappear:(BOOL)animated
{
if ([self isMovingFromParentViewController])
{
NSLog(@"View controller was popped");
}
else
{
NSLog(@"New view controller was pushed");
}
[super viewWillDisappear:animated];
}
迅捷:
override func viewWillDisappear(animated: Bool)
{
if isMovingFromParent
{
print("View controller was popped")
}
else
{
print("New view controller was pushed")
}
super.viewWillDisappear(animated)
}
来自苹果 UIViewController.h 文档:
这四个方法可以在视图控制器的外观回调中使用,以确定它是被呈现、解散、添加还是作为子视图控制器移除。例如,一个视图控制器可以通过在其 viewWillDisappear: 方法中检查表达式 ([self isBeingDismissed] || [self isMovingFromParentViewController]) 来检查它是否正在消失,因为它被解散或弹出。
- (BOOL)isBeingPresented NS_AVAILABLE_IOS(5_0);
- (BOOL)isBeingDismissed NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingToParentViewController NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingFromParentViewController NS_AVAILABLE_IOS(5_0);
因此,是的,唯一记录的方法是以下方法:
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
if ([self isBeingDismissed] || [self isMovingFromParentViewController]) {
}
}
Swift 3 版本:
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if self.isBeingDismissed || self.isMovingFromParentViewController {
}
}
Swift 4
override func viewWillDisappear(_ animated: Bool)
{
if self.isMovingFromParent
{
//View Controller Popped
}
else
{
//New view controller pushed
}
super.viewWillDisappear(animated)
}
self.navigationController
在 viewDidDisappear
中是 nil
。因此这是一个简单的替代测试。UINavigationControllerDelegate
,因为它实际上会执行真正的显示操作。)在Swift语言中:
override func viewWillDisappear(animated: Bool) {
if let navigationController = self.navigationController {
if !contains(navigationController.viewControllers as! Array<UIViewController>, self) {
}
}
super.viewWillDisappear(animated)
}
感谢 @Bryan Henry,仍然适用于Swift 5
override func viewWillDisappear(_ animated: Bool) {
super.viewWillDisappear(animated)
if let controllers = navigationController?.children{
if controllers.count > 1, controllers[controllers.count - 2] == self{
// View is disappearing because a new view controller was pushed onto the stack
print("New view controller was pushed")
}
else if controllers.firstIndex(of: self) == nil{
// View is disappearing because it was popped from the stack
print("View controller was popped")
}
}
}
extension UIViewController {
public func printTransitionStates() {
print("isBeingPresented=\(isBeingPresented)")
print("isBeingDismissed=\(isBeingDismissed)")
print("isMovingToParentViewController=\(isMovingToParentViewController)")
print("isMovingFromParentViewController=\(isMovingFromParentViewController)")
}
}
这个问题相当老了,但我无意中看到了它,所以我想发布最佳实践(据我所知)
你可以直接这样做
if([self.navigationController.viewControllers indexOfObject:self]==NSNotFound)
// view controller popped
}
这适用于iOS7,不知道是否适用于其他版本。据我所知,在viewDidDisappear
中,视图已经被弹出。这意味着当您查询self.navigationController.viewControllers
时,您将得到一个nil
。因此,只需检查它是否为零。
简而言之
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
if (self.navigationController.viewControllers == nil) {
// It has been popped!
NSLog(@"Popped and Gone");
}
}
viewWillAppear
方法中执行相同的操作,无论是通过推出视图控制器还是弹出上面的视图控制器,viewControllers
数组都是相同的!有什么想法吗? - Michael Waterfall![viewControllers containsObject:self]
而是使用了[viewControllers indexOfObject:self] == NSNotFound
?这是出于风格的选择还是其他原因? - zekelself.navigiationController.viewControllers
中。我发现检查控制器是否已呈现另一个视图控制器更容易:if (self.presentedViewController == nil)
。 - pr1001-isMovingFromParentViewController
方法允许您测试视图是否被显式弹出。 - grahamparks