如何从导航堆栈中推送/弹出uiviewcontroller时收到警报

时间:2012-01-11 07:52:21

标签: iphone ios cocoa-touch uiviewcontroller uinavigationcontroller

当我的视图控制器被从导航堆栈中推出或弹出时,我需要做某些事情,但是不想使用viewillappear / viewdidappear或viewwilldisappear / viewdiddisappear,因为除了推送/弹出视图控制器之外的那些情况。是正确的方法去使用navigationcontroller委托和navigationController:didShowViewController:animated:和navigationController:willShowViewController:animated:?如果没有,最好的方法是什么?

8 个答案:

答案 0 :(得分:7)

要了解它何时被推动,您可以使用

UINavigationControllerDelegate

并实施

- (void)navigationController:(UINavigationController *)navigationController 
      willShowViewController:(UIViewController *)viewController
                    animated:(BOOL)animated

只要将viewcontroller推入导航堆栈,并且每次弹出顶部的viewcontroller,就会触发此方法,从而再次显示它。因此,您必须使用一个标志来确定它是否已经初始化,如果它没有意味着它刚被推送。

要了解它何时被弹出,请使用以下答案:

viewWillDisappear: Determine whether view controller is being popped or is showing a sub-view controller

答案 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;

请参阅https://gist.github.com/nonamelive/9334458

答案 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)

  • (无效)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController             动画:(BOOL)动画;
  • (无效)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController             动画:(BOOL)动画;

这些委托函数不能在iOS13设备(与Xcode 11编译)上调用。这是一个错误吗?

答案 7 :(得分:0)

不好的做法是将委托设置为导航控制器层次结构中的某个内容,而不要注意通知:

UINavigationControllerWillShowViewControllerNotification

UINavigationControllerDidShowViewControllerNotification

并且userInfo对象包含“ NextVisible”和“ LastVisible”视图控制器。但是,在外观方法中使用isMoving可能是最好的方法。