Answers:
如果视图当前可见,则该视图的window属性为非nil,因此请在视图控制器中检查主视图:
调用view方法会导致视图加载(如果未加载),这是不必要的,可能是不希望的。最好先检查一下是否已经加载。我已将调用添加到isViewLoaded以避免此问题。
if (viewController.isViewLoaded && viewController.view.window) {
// viewController is visible
}
从iOS9开始,它变得更加容易:
if viewController.viewIfLoaded?.window != nil {
// viewController is visible
}
或者,如果您有一个UINavigationController管理视图控制器,则可以改为检查其visibleViewController属性。
topViewController
。
这是@progrmr的解决方案UIViewController
类别:
// UIViewController+Additions.h
@interface UIViewController (Additions)
- (BOOL)isVisible;
@end
// UIViewController+Additions.m
#import "UIViewController+Additions.h"
@implementation UIViewController (Additions)
- (BOOL)isVisible {
return [self isViewLoaded] && self.view.window;
}
@end
上述解决方案存在两个问题。例如,如果您使用a UISplitViewController
,则主视图将始终为true返回true
if(viewController.isViewLoaded && viewController.view.window) {
//Always true for master view in split view controller
}
取而代之的是,采取这种简单的方法,即使在并非所有情况下,这种方法似乎在大多数情况下也能很好地起作用:
- (void)viewDidDisappear:(BOOL)animated {
[super viewDidDisappear:animated];
//We are now invisible
self.visible = false;
}
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
//We are now visible
self.visible = true;
}
对于那些正在寻找答案的Swift 2.2版本的用户:
if self.isViewLoaded() && (self.view.window != nil) {
// viewController is visible
}
和Swift 3:
if self.isViewLoaded && (self.view.window != nil) {
// viewController is visible
}
对于全屏或上下文过多的模式表示,“可见”可能表示它在视图控制器堆栈的顶部,或者只是可见但被另一个视图控制器覆盖。
要检查视图控制器“是顶部视图控制器”与“可见”是否有很大不同,应检查视图控制器的导航控制器的视图控制器堆栈。
我写了一段代码来解决这个问题:
extension UIViewController {
public var isVisible: Bool {
if isViewLoaded {
return view.window != nil
}
return false
}
public var isTopViewController: Bool {
if self.navigationController != nil {
return self.navigationController?.visibleViewController === self
} else if self.tabBarController != nil {
return self.tabBarController?.selectedViewController == self && self.presentedViewController == nil
} else {
return self.presentedViewController == nil && self.isVisible
}
}
}
isViewLoaded
自从Swift 3.0起,FYI 就成为了一家酒店。
您要使用UITabBarController
的selectedViewController
属性。连接到选项卡栏控制器的所有视图控制器都具有tabBarController
属性集,因此您可以从任何视图控制器代码中进行操作:
if([[[self tabBarController] selectedViewController] isEqual:self]){
//we're in the active controller
}else{
//we are not
}
((UINavigationController *)self.tabBarController.selectedViewController).visibleViewController
如果您正在使用UINavigationController,并且还想处理模式视图,那么我将使用以下内容:
#import <objc/runtime.h>
UIViewController* topMostController = self.navigationController.visibleViewController;
if([[NSString stringWithFormat:@"%s", class_getName([topMostController class])] isEqualToString:@"NAME_OF_CONTROLLER_YOURE_CHECKING_IN"]) {
//is topmost visible view controller
}
我在中找到了这些功能UIViewController.h
。
/*
These four methods can be used in a view controller's appearance callbacks to determine if it is being
presented, dismissed, or added or removed as a child view controller. For example, a view controller can
check if it is disappearing because it was dismissed or popped by asking itself in its viewWillDisappear:
method by checking the expression ([self isBeingDismissed] || [self isMovingFromParentViewController]).
*/
- (BOOL)isBeingPresented NS_AVAILABLE_IOS(5_0);
- (BOOL)isBeingDismissed NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingToParentViewController NS_AVAILABLE_IOS(5_0);
- (BOOL)isMovingFromParentViewController NS_AVAILABLE_IOS(5_0);
也许上述功能可以检测到ViewController
是否出现。
如果您使用的是导航控制器,只是想知道自己是否处于活动和最顶层的控制器中,请使用:
if navigationController?.topViewController == self {
// Do something
}
该答案基于@mattdipasquale的评论。
如果您有更复杂的情况,请参见上面的其他答案。
你可以按window
财产检查
if(viewController.view.window){
// view visible
}else{
// no visible
}