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

发布于 2024-12-26 17:15:53 字数 295 浏览 7 评论 0原文

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

I need to do certain things when my view controller is both pushed or popped from the navigation stack, but don't want to use viewillappear / viewdidappear or viewwilldisappear / viewdiddisappear since those cover cases besides when the view controller is pushed / popped. Is the correct way to go about this to use the navigationcontroller delegate and the navigationController:didShowViewController:animated: and navigationController:willShowViewController:animated: ? If not, how is the best way to go about this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

半葬歌 2025-01-02 17:15:53

要查明它何时被推送,您可以使用

UINavigationControllerDelegate

并实现

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

每当视图控制器被推入导航堆栈时以及每当其顶部的视图控制器弹出时,该方法都会触发,从而显示它再次。因此,您必须使用一个标志来确定它是否已初始化,如果尚未初始化则意味着它刚刚被推送。

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

viewWillDisappear:确定视图控制器是否正在弹出或正在显示子视图控制器

To find out when it's pushed, you can use the

UINavigationControllerDelegate

and implement

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

This method will fire whenever the viewcontroller is pushed into the navigation stack, and whenever the viewcontroller on top of it is popped off, thus revealing it again. So you have to use a flag to figure out if it's been initialized yet, if it hasn't means it just was pushed.

To find out when it's been popped, use this answer:

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

任性一次 2025-01-02 17:15:53

您可以尝试当对象从导航控制器堆栈推送或弹出时调用 UINavigationController 委托方法。

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

You can try UINavigationController delegate methods it calls when object push or pop from navigation controller stack.

- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
秋凉 2025-01-02 17:15:53

下面是一个示例,用于检测视图控制器何时通过覆盖 -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");
    }
}

Here's an example to detect when a view controller is being pushed onto the navigation stack by overriding -viewWillAppear: and popped by overriding -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");
    }
}
夏有森光若流苏 2025-01-02 17:15:53

您始终可以创建 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

As pushing 将评估为 NO event 如果没有发生任何事情,则预计将从 UINavigationControllerDelegate 访问此代码。

You can always create a simple subclass of the UINavigationController and wrap its superclass's methods so that you set a flag before calling them:

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

As pushing will evaluate to NO event if nothing is happening, this code is expected to be accessed from the UINavigationControllerDelegate.

梦忆晨望 2025-01-02 17:15:53

请小心使用

- (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

Be careful to use

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

If user swipe from edge into right for popping view controller(and not actually pop it), it will invoke above delegate's function but not below function

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

Please refer to https://gist.github.com/nonamelive/9334458

深海夜未眠 2025-01-02 17:15:53

你可以在 willShowViewController 中做类似的事情

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
    if self.navigationController!.viewControllers.contains(self){
        print ("push")
    } else {
        print ("pop")
    }
}

You can do something like that in willShowViewController

func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool) {
    if self.navigationController!.viewControllers.contains(self){
        print ("push")
    } else {
        print ("pop")
    }
}
肩上的翅膀 2025-01-02 17:15:53
  • (void)navigationController:(UINavigationController *)navigationController
    willShowViewController:(UIViewController *)viewController
    动画:(BOOL)动画;
  • (void)navigationController:(UINavigationController *)navigationController
    didShowViewController:(UIViewController *)viewController
    动画:(BOOL)动画;

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

  • (void)navigationController:(UINavigationController *)navigationController
    willShowViewController:(UIViewController *)viewController
    animated:(BOOL)animated;
  • (void)navigationController:(UINavigationController *)navigationController
    didShowViewController:(UIViewController *)viewController
    animated:(BOOL)animated;

these delegate functions arent invoked on iOS13 devices (compiled with Xcode 11). Is this a bug for now?

星星的轨迹 2025-01-02 17:15:53

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

UINavigationControllerWillShowViewControllerNotification

UINavigationControllerDidShowViewControllerNotification

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

It's bad practice to set the delegate to something inside the navigation controller's hierarchy, instead observe the notifications:

UINavigationControllerWillShowViewControllerNotification

UINavigationControllerDidShowViewControllerNotification

And the userInfo object contains the "NextVisible" and "LastVisible" view controllers. However using isMoving in appearance methods is probably the best way.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文