检查视图控制器是以模态方式呈现还是在推理堆栈上推送

mea*_*ers 109 objective-c uiviewcontroller uinavigationcontroller ios swift

在我的视图控制器代码中,我如何区分:

  • 以模态呈现
  • 推送导航堆栈

这两个presentingViewControllerisMovingToParentViewControllerYES在这两种情况下,所以都不是很有益的.

令我感到困惑的是,我的父视图控制器有时是模态的,在其上推送要检查的视图控制器.

事实证明我的问题是我将我HtmlViewControllerUINavigationController内容嵌入了一个然后呈现的内容.这就是为什么我自己的尝试和下面的好答案都不起作用的原因.

HtmlViewController*     termsViewController = [[HtmlViewController alloc] initWithDictionary:dictionary];
UINavigationController* modalViewController;

modalViewController = [[UINavigationController alloc] initWithRootViewController:termsViewController];
modalViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:modalViewController
                   animated:YES
                 completion:nil];
Run Code Online (Sandbox Code Playgroud)

我想我最好告诉我的视图控制器何时是模态,而不是试图确定.

Col*_*gic 121

拿一粒盐,没试过.

- (BOOL)isModal {
     if([self presentingViewController])
         return YES;
     if([[[self navigationController] presentingViewController] presentedViewController] == [self navigationController])
         return YES;
     if([[[self tabBarController] presentingViewController] isKindOfClass:[UITabBarController class]])
         return YES;

    return NO;
 }
Run Code Online (Sandbox Code Playgroud)

  • 我在另一篇SO帖子中发现了这个.但是,如果推送的视图控制器的父级是模态,则不起作用; 这就是我所拥有的情况. (11认同)
  • 如果您提供视图控制器然后再推送另一个视图控制器,则此方法无效. (4认同)
  • 当一个`UITabBarController`被设置为根时,`presentsViewController`为推送的VC返回`YES`.所以,不适合我的情况. (3认同)
  • “如果您提供一个视图控制器,那么它会推送另一个,这是行不通的”。这不是我们的意图,不会显示被推送的视图控制器。 (3认同)
  • 正如我写的那样,`presentViewController`总是在我的情况下是'YES`; 没有帮助. (2认同)

Kin*_*ard 76

Swift中:

// MARK: - UIViewController implementation

extension UIViewController {

    var isModal: Bool {

        let presentingIsModal = presentingViewController != nil
        let presentingIsNavigation = navigationController?.presentingViewController?.presentedViewController == navigationController
        let presentingIsTabBar = tabBarController?.presentingViewController is UITabBarController

        return presentingIsModal || presentingIsNavigation || presentingIsTabBar
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 在var中应该更好,比如`var isModal:Bool {}` (3认同)
  • 你需要改变让presentingIsNavigation = navigationController?.presentingViewController?.presentedViewController == navigationController && navigationController != nil (2认同)

rma*_*ddy 72

你忽略了一种方法:isBeingPresented.

isBeingPresented 在呈现视图控制器时为true,在按下时为false.

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

    if ([self isBeingPresented]) {
        // being presented
    } else if ([self isMovingToParentViewController]) {
        // being pushed
    } else {
        // simply showing again because another VC was dismissed
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `isBeingPresented`的文档 - 只有从viewWillAppear:和viewDidAppear:方法内部调用时,此方法才返回YES. (32认同)
  • @jowie在打印原始值时使用`p`,而不是'po`.`po`用于打印对象. (3认同)
  • @Terrence似乎最新的文档没有显示该信息,但它曾经存在.`isBeingPresented`,`isBeingDismissed`,`isMovingFromParentViewController`和`isMovingToParentViewController`仅在4`视图[Will | Did] [Disa | A] ppear`方法内有效. (3认同)
  • 在发布之前我也试过这个,但它不起作用,`isBeingPresented`是'NO`.但我现在看到了原因,我将我呈现的视图控制器嵌入到`UINavigationController`中,这就是我正在推动的那个. (2认同)

Jib*_*eex 27

self.navigationController!= nil意味着它在导航堆栈中.

为了处理当导航控制器以模态方式呈现时按下当前视图控制器的情况,我添加了一些代码行来检查当前视图控制器是否是导航堆栈中的根控制器.

extension UIViewController{
func isModal() -> Bool {

    if let navigationController = self.navigationController{
        if navigationController.viewControllers.first != self{
            return false
        }
    }

    if self.presentingViewController != nil {
        return true
    }

    if self.navigationController?.presentingViewController?.presentedViewController == self.navigationController  {
        return true
    }

    if self.tabBarController?.presentingViewController is UITabBarController {
        return true
    }

    return false
   }
}
Run Code Online (Sandbox Code Playgroud)

  • 一般来说,当您以模态方式呈现时,您将 viewController 放在 navigationController 上并呈现它。如果是这种情况,您的陈述将是错误的,但是在代码中会处理这种情况。请改进您的答案:) (2认同)

Jon*_*auz 25

Swift 3
这里是解决前面答案中提到的问题的解决方案,当推送isModal()返回trueUIViewController,在给出的UINavigationController堆栈中.

extension UIViewController {
    var isModal: Bool {
        if let index = navigationController?.viewControllers.firstIndex(of: self), index > 0 {
            return false
        } else if presentingViewController != nil {
            return true
        } else if navigationController?.presentingViewController?.presentedViewController == navigationController {
            return true
        } else if tabBarController?.presentingViewController is UITabBarController {
            return true
        } else {
            return false
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

到目前为止它对我有用.如果进行一些优化,请分享.


Cha*_*tas 12

斯威夫特4

var isModal: Bool {
    return presentingViewController != nil ||
           navigationController?.presentingViewController?.presentedViewController === navigationController ||
           tabBarController?.presentingViewController is UITabBarController
}
Run Code Online (Sandbox Code Playgroud)


Kir*_*aev 10

Swift 5.干净简单。

if navigationController.presentingViewController != nil {
    // Navigation controller is being presented modally
}
Run Code Online (Sandbox Code Playgroud)


Meh*_*san 9

Swift 5
这个方便的扩展比以前的答案处理更多的情况。这些情况是 VC(视图控制器)是应用程序窗口的根 VC,VC 作为子 VC 添加到父 VC。仅当视图控制器以模态方式呈现时,它才会尝试返回 true。

extension UIViewController {
    /**
      returns true only if the viewcontroller is presented.
    */
    var isModal: Bool {
        if let index = navigationController?.viewControllers.firstIndex(of: self), index > 0 {
            return false
        } else if presentingViewController != nil {
            if let parent = parent, !(parent is UINavigationController || parent is UITabBarController) {
                return false
            }
            return true
        } else if let navController = navigationController, navController.presentingViewController?.presentedViewController == navController {
            return true
        } else if tabBarController?.presentingViewController is UITabBarController {
            return true
        }
        return false
    }
}
Run Code Online (Sandbox Code Playgroud)

谢乔纳兹的回答。同样,还有更多优化的空间。需要处理的案例请在评论区讨论。