ios 是否可以确定 ViewController 是否显示为 Modal?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2798653/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-30 17:12:59  来源:igfitidea点击:

Is it possible to determine whether ViewController is presented as Modal?

iphoneiosviewcontrollermodal-dialog

提问by lukewar

Is it possible to check inside ViewController class that it is presented as modal view controller?

是否可以在 ViewController 类内部检查它是否显示为模态视图控制器?

回答by Gabriele Petronella

Since modalViewControllerhas been deprecated in iOS 6, here's a version that works for iOS 5+ and that compiles without warnings.

由于modalViewController已在 iOS 6 中弃用,这里有一个适用于 iOS 5+ 并且编译时没有警告的版本。

Objective-C:

目标-C:

- (BOOL)isModal {
    return self.presentingViewController.presentedViewController == self
      || (self.navigationController != nil && self.navigationController.presentingViewController.presentedViewController == self.navigationController)
      || [self.tabBarController.presentingViewController isKindOfClass:[UITabBarController class]];
}

Swift:

迅速:

var isModal: Bool {
    return self.presentingViewController?.presentedViewController == self
        || (self.navigationController != nil && self.navigationController?.presentingViewController?.presentedViewController == self.navigationController)
        || self.tabBarController?.presentingViewController is UITabBarController
}

Hat tip to Felipe's answer.

Felipe 的回答的帽子提示。

回答by Felipe Sabino

If you a looking for iOS 6+, this answer is deprecated and you should check Gabriele Petronella's answer

如果您正在寻找 iOS 6+,则不推荐使用此答案,您应该查看Gabriele Petronella 的答案



There is no neat way to do that, as a property or method native to UIKit. What you can do is to check several aspects of your controller to ensure it is presented as modal.

作为 UIKit 原生的属性或方法,没有什么巧妙的方法可以做到这一点。您可以做的是检查控制器的几个方面,以确保它显示为模态。

So, to check if the current(represented as selfin the code bellow) controller is presented in a modal way or not, I have the function bellow either in a UIViewControllercategory, or (if your project does not need to use other UIKit controllers, as UITableViewControllerfor example) in a base controller that my other controllers inherit of

因此,要检查当前(如self以下代码所示)控制器是否以模态方式呈现,我在UIViewController类别中具有以下功能,或者(如果您的项目不需要使用其他 UIKit 控制器,如UITableViewController例如)在我的其他控制器继承的基本控制器中

-(BOOL)isModal {

     BOOL isModal = ((self.parentViewController && self.parentViewController.modalViewController == self) || 
            //or if I have a navigation controller, check if its parent modal view controller is self navigation controller
            ( self.navigationController && self.navigationController.parentViewController && self.navigationController.parentViewController.modalViewController == self.navigationController) || 
            //or if the parent of my UITabBarController is also a UITabBarController class, then there is no way to do that, except by using a modal presentation
            [[[self tabBarController] parentViewController] isKindOfClass:[UITabBarController class]]);

    //iOS 5+
    if (!isModal && [self respondsToSelector:@selector(presentingViewController)]) {

        isModal = ((self.presentingViewController && self.presentingViewController.modalViewController == self) || 
             //or if I have a navigation controller, check if its parent modal view controller is self navigation controller
             (self.navigationController && self.navigationController.presentingViewController && self.navigationController.presentingViewController.modalViewController == self.navigationController) || 
             //or if the parent of my UITabBarController is also a UITabBarController class, then there is no way to do that, except by using a modal presentation
             [[[self tabBarController] presentingViewController] isKindOfClass:[UITabBarController class]]);

    }

    return isModal;        

}

EDIT: I added the last check to see if a UITabBarController is being used, and you present another UITabBarController as modal.

编辑:我添加了最后一个检查以查看是否正在使用 UITabBarController,并且您将另一个 UITabBarController 呈现为模态。

EDIT 2: added iOS 5+ check, where UIViewControllerdoes not answer for parentViewControlleranymore, but to presentingViewControllerinstead.

编辑 2:添加了 iOS 5+ 检查,这里UIViewController不再回答parentViewController,而是presentingViewController改为。

EDIT 3: I've created a gist for it just in case https://gist.github.com/3174081

编辑 3:我为它创建了一个要点以防万一https://gist.github.com/3174081

回答by Raj

In iOS5+, As you can see in UIViewController Class Reference, you can get it from property "presentingViewController".

在 iOS5+ 中,正如您在UIViewController Class Reference 中看到的那样,您可以从属性“presentingViewController”中获取它。

presentingViewController The view controller that presented this view controller. (read-only)

presentingViewController 呈现此视图控制器的视图控制器。(只读)

@property(nonatomic, readonly) UIViewController *presentingViewController
Discussion

@property(nonatomic, readonly) UIViewController *presentingViewController
讨论

If the view controller that received this message is presented by another view controller, this property holds the view controller that is presenting it. If the view controller is not presented, but one of its ancestors is being presented, this property holds the view controller presenting the nearest ancestor. If neither the view controller nor any of its ancestors are being presented, this property holds nil.

如果接收此消息的视图控制器由另一个视图控制器呈现,则此属性保存呈现它的视图控制器。如果未呈现视图控制器,但正在呈现其祖先之一,则此属性保存呈现最近祖先的视图控制器。如果视图控制器及其任何祖先都没有呈现,则此属性为 nil。

Availability
Available in iOS 5.0 and later.
Declared In
UIViewController.h

可用性
在 iOS 5.0 及更高版本中可用。

UIViewController.h 中声明

回答by hpique

If there isn't, you can define a property for this (presentedAsModal) in your UIViewController subclass and set it to YESbefore presenting the ViewController as a modal view.

如果没有,您可以presentedAsModal在 UIViewController 子类中为 this ( )定义一个属性,并YES在将 ViewController 作为模态视图呈现之前将其设置为。

childVC.presentedAsModal = YES;
[parentVC presentModalViewController:childVC animated:YES];

You can check this value in your viewWillAppearoverride.

您可以在viewWillAppear覆盖中检查此值。

I believe there isn't an official property that states how the view is presented, but nothing prevents you from creating your own.

我相信没有官方属性说明视图的呈现方式,但是没有什么可以阻止您创建自己的。

回答by Semih Cihan

Petronella's answerdoes not work if self.navigationController is modally presented but self is not equal to self.navigationController.viewControllers[0], in that case self is pushed.

如果 self.navigationController 以模态呈现但 self 不等于 self.navigationController.viewControllers[0],则Petronella 的答案不起作用,在这种情况下,self 被推送。

Here is how you could fix the problem.

以下是解决问题的方法。

return self.presentingViewController.presentedViewController == self
            || (self.navigationController != nil && self.navigationController.presentingViewController.presentedViewController == self.navigationController && self == self.navigationController.viewControllers[0])
            || [self.tabBarController.presentingViewController isKindOfClass:[UITabBarController class]];

And in Swift:

在 Swift 中:

return self.presentingViewController?.presentedViewController == self
        || (self.navigationController != nil && self.navigationController?.presentingViewController?.presentedViewController == self.navigationController && self.navigationController?.viewControllers[0] == self)
        || self.tabBarController?.presentingViewController is UITabBarController

回答by kubi

This should work.

这应该有效。

if(self.parentViewController.modalViewController == self)…

回答by Sunny Shah

Best way to check

最好的检查方法

 if (self.navigationController.presentingViewController) {
         NSLog(@"Model Present");
    }

回答by arlomedia

If you don't need to distinguish between full-screen modal views and non-modal views, which is the case in my project (I was dealing with a problem that only occurs with form sheets and page sheets), you can use the modalPresentationStyle property of UIViewController:

如果不需要区分全屏模态视图和非模态视图,在我的项目中就是这种情况(我在处理一个只出现在表单和页表上的问题),可以使用modalPresentationStyle UIViewController 的属性:

switch (self.modalPresentationStyle) {
    case 0: NSLog(@"full screen, or not modal"); break;
    case 1: NSLog(@"page sheet"); break;
    case 2: NSLog(@"form sheet"); break;
}

回答by King-Wizard

In Swift:

斯威夫特

func isUIViewControllerPresentedAsModal() -> Bool {
    if((self.presentingViewController) != nil) {
        return true
    }

    if(self.presentingViewController?.presentedViewController == self) {
        return true
    }

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

    if((self.tabBarController?.presentingViewController?.isKindOfClass(UITabBarController)) != nil) {
        return true
    }

    return false
}

回答by Olex

In my project I have a view controller (Detail) that can be presented either modally (when adding a new item) or with push (when editing an existing one) by Master view controller. When user taps [Done] the Detail view controller calls Master view controller's method to notify that it is ready to be closed. Master has to determine how Detail is presented in order to know how to close it. This is how I do this:

在我的项目中,我有一个视图控制器(Detail),它可以通过主视图控制器以模态(添加新项目时)或推送(编辑现有项目时)方式呈现。当用户点击 [Done] 时,Detail 视图控制器调用主视图控制器的方法来通知它已准备好关闭。Master 必须确定 Detail 是如何呈现的,以便知道如何关闭它。这就是我这样做的方式:

UIViewController *vc = self.navigationController.viewControllers.lastObject;
if (vc == self) {
    [self dismissViewControllerAnimated:YES completion:NULL];
} else {
    [self.navigationController popViewControllerAnimated:YES];
}