我在视图控制器代码中如何区分:
在这两种情况下,presentingViewController
和isMovingToParentViewController
都是YES
,所以不是很有帮助。
使问题复杂化的是我的父视图控制器有时是模态的,在其上推送要检查的视图控制器。
事实证明,我的问题是我将HtmlViewController
嵌入UINavigationController
,然后展示。这就是为什么我自己的尝试以及下面的好答案都没有起作用。
HtmlViewController* termsViewController = [[HtmlViewController alloc] initWithDictionary:dictionary];
UINavigationController* modalViewController;
modalViewController = [[UINavigationController alloc] initWithRootViewController:termsViewController];
modalViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:modalViewController
animated:YES
completion:nil];
我想我最好告诉我的视图控制器什么时候模态,而不是试图确定。
答案 0 :(得分:113)
带上一粒盐,没有进行测试。
- (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;
}
答案 1 :(得分:68)
您忽略了一种方法: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
}
}
答案 2 :(得分:64)
在 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
}
}
答案 3 :(得分:20)
self.navigationController!= nil意味着它在导航中 叠加。
为了处理当导航控制器以模态方式呈现时按下当前视图控制器的情况,我添加了一些代码行来检查当前视图控制器是否是导航堆栈中的根控制器。
MySQL
答案 4 :(得分:17)
斯威夫特3
如果推送isModal()
在呈现的true
堆栈中,则UIViewController
返回UINavigationController
时,此解决方案可解决之前答案中提到的问题。
extension UIViewController {
var isModal: Bool {
if let index = navigationController?.viewControllers.index(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
}
}
}
到目前为止它对我有用。 如果进行了一些优化,请分享。
答案 5 :(得分:12)
Swift 4
var isModal: Bool {
return presentingViewController != nil ||
navigationController?.presentingViewController?.presentedViewController === navigationController ||
tabBarController?.presentingViewController is UITabBarController
}
答案 6 :(得分:3)
正如这里的许多人建议的那样,"检查"方法不适用于所有情况,在我的项目中,我提出了手动管理的解决方案。 关键是,我们通常自己管理演示文稿 - 这不是幕后发生的事情,我们必须反省。
DEViewController.h
档案:
#import <UIKit/UIKit.h>
// it is a base class for all view controllers within a project
@interface DEViewController : UIViewController
// specify a way viewcontroller, is presented by another viewcontroller
// the presented view controller should manually assign the value to it
typedef NS_ENUM(NSUInteger, SSViewControllerPresentationMethod) {
SSViewControllerPresentationMethodUnspecified = 0,
SSViewControllerPresentationMethodPush,
SSViewControllerPresentationMethodModal,
};
@property (nonatomic) SSViewControllerPresentationMethod viewControllerPresentationMethod;
// other properties/methods...
@end
现在可以通过这种方式管理演示文稿:
推送到导航堆栈:
// DETestViewController inherits from DEViewController
DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodPush;
[self.navigationController pushViewController:vc animated:YES];
以模式显示导航:
DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodModal;
UINavigationController *nav = [[UINavigationController alloc]
initWithRootViewController:vc];
[self presentViewController:nav animated:YES completion:nil];
以模态方式呈现:
DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodModal;
[self presentViewController:vc animated:YES completion:nil];
另外,在DEViewController
中,我们可以添加一个回退到&#34;检查&#34;如果上述属性等于SSViewControllerPresentationMethodUnspecified
:
- (BOOL)isViewControllerPushed
{
if (self.viewControllerPresentationMethod != SSViewControllerPresentationMethodUnspecified) {
return (BOOL)(self.viewControllerPresentationMethod == SSViewControllerPresentationMethodPush);
}
else {
// fallback to default determination method
return (BOOL)self.navigationController.viewControllers.count > 1;
}
}
答案 7 :(得分:3)
假设您以模态方式呈现的所有viewControllers都包含在一个新的navigationController中(您应该始终这样做),您可以将此属性添加到VC中。
private var wasPushed: Bool {
guard let vc = navigationController?.viewControllers.first where vc == self else {
return true
}
return false
}
答案 8 :(得分:2)
self.navigationController != nil
意味着它在导航堆栈中。
答案 9 :(得分:2)
迅速5。简洁。
if navigationController.presentingViewController != nil {
// Navigation controller is being presented modally
}
答案 10 :(得分:2)
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
}
}
感谢Jonauz's answer。同样,还有进行更多优化的空间。请在注释部分中讨论需要处理的情况。
答案 11 :(得分:1)
要检测您的控制器是否被按下,只需在您想要的任何地方使用以下代码:
if ([[[self.parentViewController childViewControllers] firstObject] isKindOfClass:[self class]]) {
// Not pushed
}
else {
// Pushed
}
我希望这段代码可以帮助任何人...
答案 12 :(得分:0)
如果您使用的是ios 5.0或更高版本,请使用此代码
-(BOOL)isPresented
{
if ([self isBeingPresented]) {
// being presented
return YES;
} else if ([self isMovingToParentViewController]) {
// being pushed
return NO;
} else {
// simply showing again because another VC was dismissed
return NO;
}
}
答案 13 :(得分:0)
if let navigationController = self.navigationController, navigationController.isBeingPresented {
// being presented
}else{
// being pushed
}
答案 14 :(得分:-1)
id presentedController = self.navigationController.modalViewController;
if (presentedController) {
// Some view is Presented
} else {
// Some view is Pushed
}
这将告诉您是否呈现或推送了viewController
答案 15 :(得分:-1)
对于某些想知道的人,如何告诉ViewController它正在呈现
如果adb devices
正在展示/推送A
在B
enum
和property
B
现在在enum ViewPresentationStyle {
case Push
case Present
}
//and write property
var vcPresentationStyle : ViewPresentationStyle = .Push //default value, considering that B is pushed
视图控制器中,通过分配A
B
是否正在显示/推送它
presentationStyle
func presentBViewController() {
let bViewController = B()
bViewController.vcPresentationStyle = .Present //telling B that it is being presented
self.presentViewController(bViewController, animated: true, completion: nil)
}
视图控制器
B