弹出顶部时,视图控制器的iOS如何以编程方式检测?(iOS how to detect progra

2019-06-28 06:08发布

假设我有与2个视图控制器一个导航控制器堆栈:VC2是在顶部和VC1是下面。 有没有代码,我可以包括VC1将检测VC2刚刚弹出堆栈?

因为我想从VC1似乎像viewWillAppear中viewDidAppear将无法工作在代码中检测VC2的弹起,因为这些方法火是显示每次VC1,包括当它第一次压入堆栈。

编辑:看来我也不是很清楚跟我原来的问题。 这里就是我想要做的事:确定何时正在显示由于VC2 VC1被弹出堆栈的顶部。 下面是我不想做的事:确定何时VC1正在显示由于被压入堆栈的顶部。 我需要一些方法,能够检测的第一个动作,但不是第二个动作。

注:我并不特别在意VC2,它可以是任何数字,得到出栈其他风投的,我关心的是,当VC1再次成为堆栈的顶部,由于一些其他的VC开始弹出的最佳。

Answer 1:

iOS 5中引入了两个新的方法来处理正是这种类型的情况。 什么你要找的是-[UIViewController isMovingToParentViewController] 从文档 :

isMovingToParentViewController

返回一个布尔值,指示该视图控制器处于被添加到父的过程。

- (BOOL)isMovingToParentViewController

返回值
YES如果视图控制器出现,因为它被添加作为容器视图控制器的子级,否则NO。

讨论
此方法返回YES从下列方法中调用,只有当:

-viewWillAppear:
-viewDidAppear:

你的情况,你可以实现-viewWillAppear:像这样:

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];

    if (self.isMovingToParentViewController == NO)
    {
        // we're already on the navigation stack
        // another controller must have been popped off
    }
}

编辑:有一个微妙的语义差别考虑在这里,你有兴趣的事实,VC2尤其是弹出堆栈,或者你希望每个VC1透露任何控制器大跌眼镜的结果时都收到通知? 在前一种情况下,代表团是一个更好的解决方案。 一个直线上升的弱引用VC1也可以工作,如果你从来没有重用VC2打算。

编辑2:我制造的实施例通过反转逻辑和不早返回更加明确。



Answer 2:

isMovingTo / FromParentViewController不会为推动和弹出到导航控制器栈工作。

这里有一个可靠的方式来做到这一点(不使用代理),但它只是大概的iOS 7+。

UIViewController *fromViewController = [[[self navigationController] transitionCoordinator] viewControllerForKey:UITransitionContextFromViewControllerKey];

if ([[self.navigationController viewControllers] containsObject:fromViewController])
{
    //we're being pushed onto the nav controller stack.  Make sure to fetch data.
} else {
    //Something is being popped and we are being revealed
}

在我的情况下,使用该委托将意味着具有视图控制器的行为可更紧密地耦合与拥有的资产净值堆委托,我想更独立的解决方案。 这工作。



Answer 3:

你可以接近这一点的一种方法是申报VC2像这样一个委托协议:

在VC1.h

@interface VC1 : UIViewController <VC2Delegate> {
...
}

在VC1.m

-(void)showVC2 {
    VC2 *vc2 = [[VC2 alloc] init];
    vc2.delegate = self;
    [self.navigationController pushViewController:vc2 animated:YES];
}

-(void)VC2DidPop {
    // Do whatever in response to VC2 being popped off the nav controller
}

在VC2.h

@protocol VC2Delegate <NSObject>
-(void)VC2DidPop;
@end

@interface VC2 : UIViewController {

    id<VC2Delegate> delegate;
}

@property (nonatomic, assign) id delegate;

...

@end

VC2.m

-(void)viewDidUnload {
    [super viewDidUnload];
    [self.delegate VC2DidPop];
}

有一个关于协议和代表的基础知识的好文章在这里 。



Answer 4:

您也可以检测正在被弹出视图控制器

- (void)viewWillDisappear:(BOOL)animated {
    [super viewWillDisappear:animated];

    if ([self isMovingFromParentViewController]) {
        ....
    }
}


Answer 5:

这是为我工作

UIViewController *fromViewController = [[[self navigationController] transitionCoordinator] viewControllerForKey:UITransitionContextFromViewControllerKey];
if (![[self.navigationController viewControllers] containsObject:fromViewController] && !self.presentedViewController)
{
  //Something is being popped and we are being revealed 
}


Answer 6:

什么是你特别想干什么?

如果你想检测VC1即将被显示, 这个答案应该帮助你。 使用UINavigationControllerDelegate 。

如果你想检测VC2即将被隐藏的,我只想用viewWillDisappear: VC2的。



Answer 7:

SWIFT 3

override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        if self.isMovingToParentViewController {
            print("View is moving to ParentViewControll")
        }
}


Answer 8:

我得到了相同的情况,但有轻微的更具体的使用情况。 在我的情况下,我们想确定是否VC1时,会出现/显示时,其中VC2上navigationController在VC1推VC2上的后退按钮用户点击。

所以我用的帮助snarshad的回答来定制按我的需要。 这里是VC1的码viewDidAppear迅速3。

// VC1: ParentViewController
// VC2: ChildViewController

    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

        if let transitionCoordinator = navigationController?.transitionCoordinator,
            let fromVC = transitionCoordinator.viewController(forKey: UITransitionContextViewControllerKey.from),
            let toVC = transitionCoordinator.viewController(forKey: UITransitionContextViewControllerKey.to),
            fromVC is ChildViewController,
            toVC is ParentViewController {

            print("Back button pressed on ChildViewController, and as a result ParentViewController appeared")
        }
    }


Answer 9:

是的,VC1,您可以检查是否VC2弹出与否。 UINavigationController的有一种方法viewControllers这将返回推控制器 ,这是在所述堆的阵列(即,已按下)。

所以,你通过比较通过类重复循环。 如果VC2是存在的,都会有比赛,否则不是。



Answer 10:

您可以为NSNotification专门增加一个观察者只为您的VC2。

// pasing the "VC2" here will tell the notification to only listen for notification from
// VC2 rather than every single other objects
[[NSNotitificationCenter defaultCenter] addObserver:self selector:@selector(doSomething:) object:VC2];

现在,在您的VC2的观点就会消失,你可以发布一个通知:

-(void)viewWillDisappear
{
    [[NSNotificationCenter defaultCenter] postNotificationNamed:@"notif_dismissingVC2" object:nil];
}


文章来源: iOS how to detect programmatically when top view controller is popped?