如何判断UIViewController的视图中可见如何判断UIViewController的视图中

2019-05-10 10:21发布

我有一个标签栏的应用程序,有许多意见。 有没有办法知道,如果一个特定UIViewController是目前可见的距离之内UIViewController ? (找物业)

Answer 1:

视图的窗口属性是非零如果一个观点是目前可见的,所以您在视图控制器的主要观点:

调用视图方法使视图以负载(如果它尚未装载的话)其是不必要的,并且可能是不期望的。 这将是最好先检查一下,看是否已经被加载它。 我已经添加了调用isViewLoaded避免这个问题。

if (viewController.isViewLoaded && viewController.view.window) {
    // viewController is visible
}

或者,如果你有一个UINavigationController管理视图控制器,你可以检查其visibleViewController属性。

另外,在夫特在iOS 9(或更高版本):

if viewController.viewIfLoaded?.window != nil {
    // viewController is visible
}


Answer 2:

这里的@ 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


Answer 3:

有一对夫妇的上述解决方案的问题。 如果您正在使用,例如UISplitViewController ,主视图将始终返回真

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;
}


Answer 4:

对于那些寻找一个雨燕2.2版本的答案:

if self.isViewLoaded() && (self.view.window != nil) {
     // viewController is visible
}

斯威夫特3:

if self.isViewLoaded && (self.view.window != nil) {
         // viewController is visible
}


Answer 5:

你想使用UITabBarControllerselectedViewController财产。 附连到标签栏控制器的所有视图控制器具有tabBarController属性集,这样就可以,从内的任何视图控制器的代码的:

if([[[self tabBarController] selectedViewController] isEqual:self]){
     //we're in the active controller
}else{
     //we are not
}


Answer 6:

对于在全屏或过度背景模式的介绍,“可见”可能意味着它是在视图控制器堆栈的顶部或只是可见的,而是由另一视图控制器覆盖。

要检查是否视图控制器“是顶视图控制器”是从“可见”完全不同,你应该检查视图控制器的导航控制器的视图控制器堆栈。

我写了一段代码来解决这个问题:

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
        }
    }
}


Answer 7:

我做了基于@ progrmr的回答迅速扩展。

它可以让你轻松地检查是否UIViewController是在屏幕上,如下所示:

if someViewController.isOnScreen {
    // Do stuff here
}

扩展:

//
//  UIViewControllerExtension.swift
//

import UIKit

extension UIViewController{
    var isOnScreen: Bool{
        return self.isViewLoaded() && view.window != nil
    }
}


Answer 8:

对于我而言,在容器视图控制器的情况下,我发现,

- (BOOL)isVisible {
    return (self.isViewLoaded && self.view.window && self.parentViewController != nil);
}

效果很好。



Answer 9:

如果你正在使用一个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
}


Answer 10:

我用于一个模式呈现视图控制器的方法是检查类所呈现的控制器。 如果目前的视图控制器是ViewController2那么我会执行一些代码。

UIViewController *vc = [self presentedViewController];

if ([vc isKindOfClass:[ViewController2 class]]) {
    NSLog(@"this is VC2");
}


Answer 11:

我发现这些功能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的出现与否。



Answer 12:

的XCode 6.4,为iOS 8.4,启用ARC

显然,大量的做这件事的方式。 已经为我工作的一个如下...

@property(nonatomic, readonly, getter=isKeyWindow) BOOL keyWindow

这可以以任何视图控制器一起使用以下列方式,

[self.view.window isKeyWindow]

如果调用此属性-(void)viewDidLoad你得到0,那么如果调用此之后-(void)viewDidAppear:(BOOL)animated你得到1。

希望这可以帮助别人。 谢谢! 干杯。



Answer 13:

如果您使用的是导航控制器,只是想知道你是不是在活跃最上面的控制器,然后使用:

if navigationController?.topViewController == self {
    // Do something
}

这个答案是基于@mattdipasquale的评论。

如果你有更复杂的情形,看到上面的答案。



Answer 14:

您可以通过检查window属性

if(viewController.view.window){

// view visible

}else{

// no visible

}


Answer 15:

我需要这个来检查视图控制器是当前观看控制器,I通过检查,如果有任何呈现视图控制器或者通过导航仪推做到了,我张贴的情况下,任何人都需要这样的解决方案:

if presentedViewController != nil || navigationController?.topViewController != self {
      //Viewcontroller isn't viewed
}else{
     // Now your viewcontroller is being viewed 
}


文章来源: How to tell if UIViewController's view is visible