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
Is it possible to determine whether ViewController is presented as Modal?
提问by lukewar
Is it possible to check inside ViewController class that it is presented as modal view controller?
是否可以在 ViewController 类内部检查它是否显示为模态视图控制器?
回答by Gabriele Petronella
Since modalViewController
has 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 self
in the code bellow) controller is presented in a modal way or not, I have the function bellow either in a UIViewController
category, or (if your project does not need to use other UIKit controllers, as UITableViewController
for 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 UIViewController
does not answer for parentViewController
anymore, but to presentingViewController
instead.
编辑 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 YES
before 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 viewWillAppear
override.
您可以在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];
}