从导航堆栈推送/弹出uiviewcontroller时如何收到警报
Posted
技术标签:
【中文标题】从导航堆栈推送/弹出uiviewcontroller时如何收到警报【英文标题】:How to be alerted when uiviewcontroller is pushed / popped from navigation stack 【发布时间】:2012-01-11 07:52:21 【问题描述】:当我的视图控制器被推送或从导航堆栈中弹出时,我需要做某些事情,但我不想使用 viewillappear / viewdidappear 或 viewwilldisappear / viewdiddisappear,因为除了视图控制器被推送/弹出时,这些情况下.使用 navigationcontroller 委托和 navigationController:didShowViewController:animated: 和 navigationController:willShowViewController:animated: 的正确方法是吗?如果没有,最好的方法是什么?
【问题讨论】:
【参考方案1】:要了解它何时被推送,您可以使用
UINavigationControllerDelegate
并实施
- (void)navigationController:(UINavigationController *)navigationController
willShowViewController:(UIViewController *)viewController
animated:(BOOL)animated
每当视图控制器被推入导航堆栈时,以及其顶部的视图控制器被弹出时,此方法都会触发,从而再次显示它。所以你必须使用一个标志来确定它是否已经被初始化,如果它还没有意味着它只是被推送。
要了解它何时被弹出,请使用以下答案:
viewWillDisappear: Determine whether view controller is being popped or is showing a sub-view controller
【讨论】:
【参考方案2】:当对象从导航控制器堆栈中推送或弹出时,您可以尝试 UINavigationController 委托方法。
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
- (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated;
【讨论】:
【参考方案3】:这是一个示例,用于检测何时通过覆盖 -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");
【讨论】:
Overriding
是一个更好的词。【参考方案4】:
您始终可以创建 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
事件,因此预计将从 UINavigationControllerDelegate 访问此代码。
【讨论】:
【参考方案5】:谨慎使用
- (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
【讨论】:
【参考方案6】:你可以在 willShowViewController 中做类似的事情
func navigationController(navigationController: UINavigationController, willShowViewController viewController: UIViewController, animated: Bool)
if self.navigationController!.viewControllers.contains(self)
print ("push")
else
print ("pop")
【讨论】:
【参考方案7】: (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController 动画:(BOOL)动画; (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController 动画:(BOOL)动画;这些委托函数不会在 ios13 设备(使用 Xcode 11 编译)上调用。这是目前的错误吗?
【讨论】:
【参考方案8】:将委托设置为导航控制器层次结构内的某些东西是不好的做法,而是观察通知:
UINavigationControllerWillShowViewControllerNotification
UINavigationControllerDidShowViewControllerNotification
并且 userInfo 对象包含“NextVisible”和“LastVisible”视图控制器。但是在外观方法中使用isMoving
可能是最好的方法。
【讨论】:
以上是关于从导航堆栈推送/弹出uiviewcontroller时如何收到警报的主要内容,如果未能解决你的问题,请参考以下文章