如果存在多个视图控制器,如何关闭模式视图控制器

Posted

技术标签:

【中文标题】如果存在多个视图控制器,如何关闭模式视图控制器【英文标题】:How to dismiss modal view controller if there are multiple view controller are presented 【发布时间】:2016-04-24 14:16:25 【问题描述】:

我有一个视图控制器 A,它具有表视图并基于行选择,我将以模态方式打开另一个视图控制器 B。我还为我的应用程序实现了不活动计时器。现在,当 B 出现并且 A 正在呈现控制器并且由于用户不活动时,另一个视图控制器不活动视图控制器 C 将以模态方式在 B 之上打开。这意味着我有 A ,然后 B 在 A 之上,C 在之上B. 现在,用户从 C 中单击了一个按钮进行注销,我只能关闭 C。但视图控制器 B 永远不会被关闭。

不活动是使用触摸事件和通知实现的,通知在当前视图之上以模态方式呈现不活动视图控制器,如下面的代码所述。

- (void) applicationDidTimeout:(NSNotification *) notif

    NSLog(@"Application Did Timeout ...");

    BCDSessionInactivityViewController *sessionView=[[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"InactivityViewController"];

    sessionView.modalPresentationStyle = UIModalPresentationFormSheet;
    sessionView.preferredContentSize =  CGSizeMake(838,340);
    UIViewController *parentController = self.parentViewController;
    NSLog(@"presenting view controller is %@", [parentController class]);

    [[self topViewController]presentViewController:sessionView animated:YES completion:nil];





- (UIViewController *)topViewController
    return [self topViewController:[UIApplication sharedApplication].keyWindow.rootViewController];




- (UIViewController *)topViewController:(UIViewController *)rootViewController

    if (rootViewController.presentedViewController == nil) 
        return rootViewController;
    

    if ([rootViewController.presentedViewController isMemberOfClass:[UINavigationController class]]) 
        UINavigationController *navigationController = (UINavigationController *)rootViewController.presentedViewController;
        UIViewController *lastViewController = [[navigationController viewControllers] lastObject];
        return [self topViewController:lastViewController];
    

    UIViewController *presentedViewController = (UIViewController *)rootViewController.presentedViewController;
    return [self topViewController:presentedViewController];

有什么方法可以让我也解散控制器 B 吗?

在我关闭视图控制器 C 的视图控制器 C 方法中,我根据建议编辑代码,但视图控制器 B 仍然没有被关闭。

- (IBAction)logoutbtn:(id)sender

    NSLog(@"logout is called");
    if ([self.presentingViewController isKindOfClass:[BCDScanReviewViewController class]] || [[[F7CheckScanner instance]checkFrontScanned] isEqualToString:@"checkFrontScanned"])
         
             NSLog(@"check front scanned %@",[[F7CheckScanner instance]checkFrontScanned]);
             [[F7CheckScanner instance]scanBackOfCheckNoData];
         
    [sessionTimer invalidate];
    sessionTimer = nil;
    [[BCDTimeManager sharedTimerInstance]stopIdleTimer];

    [self dismissViewControllerAnimated:YES completion:^()

        [self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:^();
             BCDThankYouViewController  *thankuView=[[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"ThankyouView"];
             [[self topViewController ]presentViewController:thankuView animated:YES completion:nil];
         ];
    ];



    UIViewController *parentController = self.presentingViewController;
    NSLog(@"presenting view controller is %@", [parentController class]);
   // [self dismissViewControllerAnimated:YES completion:^() 
   //     [parentController performSegueWithIdentifier:COMMON_VC_TO_THANK_YOU_VC sender:self];
   // ];



【问题讨论】:

由于您使用的是 NavigationController,因此您可以使用 unwind segue。见答案here。 使用dismissViewControllerAnimated方法的完成块,在那里你可以再次调用ViewController B的dismissViewControllerAnimated。 @iamyogish;我已经编辑了问题,它没有按照建议工作。你能看看我是不是做错了什么 【参考方案1】:

你可以从C 做类似的事情,

[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];

[self dismissViewControllerAnimated:YES completion:^ /* do something when the animation is completed */ ];
[self.parentViewController dismissViewControllerAnimated:YES completion:^ /* do something when the animation is completed */ ];

根据评论更新:

更换你的

[self dismissViewControllerAnimated:YES completion:^()

    [self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:^();
         BCDThankYouViewController  *thankuView=[[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"ThankyouView"];
         [[self topViewController ]presentViewController:thankuView animated:YES completion:nil];
     ];
];

[self.presentingViewController.presentingViewController dismissViewControllerAnimated:YES completion:nil];

 //you can do something here in completion instead of nil. 

如果你想关闭三个视图控制器,那么你可以使用self.presentingViewController.presentingViewController.presentingViewController

希望这会有所帮助:)

【讨论】:

@ Lion :我在 Viewcontroller C 中有以下方法可以解除 C,在这里我根据您的评论添加了代码。但它没有解除控制器 B。你能看看这个吗?我已经编辑了问题【参考方案2】:

这样解雇

//remove
    [self removeFromParentViewController];
    [self didMoveToParentViewController:nil];
    [self.view removeFromSuperview];

【讨论】:

【参考方案3】:

感谢大家的建议。我在其他 SO 帖子的帮助下解决了这个问题。这是解决方案

-(void)dismissModalStack 
    UIViewController *vc = self.presentingViewController;
    while (vc.presentingViewController) 
        vc = vc.presentingViewController;
    

    NSLog(@"Dismissing the view controller at root of view hiearchy: %@", [vc class]);

    [vc dismissViewControllerAnimated:YES completion:^() 
        BCDThankYouViewController  *thankuView=[[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"ThankyouView"];
        [[self topViewController ]presentViewController:thankuView animated:YES completion:nil];
    ];

【讨论】:

以上是关于如果存在多个视图控制器,如何关闭模式视图控制器的主要内容,如果未能解决你的问题,请参考以下文章

关闭模式视图控制器后如何正确对齐 rightBarButtonItem?

同时关闭多个视图控制器

视图控制器堆栈

关闭多个视图控制器

呈现和关闭模式视图控制器时如何保持选择集合视图单元格?

在应用程序退出时关闭模式视图控制器