ios 如何判断 UIViewController 的视图是否可见

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2777438/
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:11:54  来源:igfitidea点击:

How to tell if UIViewController's view is visible

iosuiviewuiviewcontrolleruiwindow

提问by Rob Bonner

I have a tab bar application, with many views. Is there a way to know if a particular UIViewControlleris currently visible from within the UIViewController? (looking for a property)

我有一个标签栏应用程序,有很多视图。有没有办法知道,如果一个特定的UIViewController,目前从内部可见UIViewController?(寻找房产)

回答by progrmr

The view's window propertyis non-nil if a view is currently visible, so check the main view in the view controller:

如果视图当前可见,则视图的window 属性为非 nil,因此请检查视图控制器中的主视图:

Invoking the viewmethod causes the view to load (if it is not loaded) which is unnecessary and may be undesirable. It would be better to check first to see if it is already loaded. I've added the call to isViewLoaded to avoid this problem.

调用view方法会导致加载(如果未加载)视图,这是不必要的并且可能是不可取的。最好先检查它是否已经加载。我已将调用添加到 isViewLoaded 以避免此问题。

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

Since iOS9 it has became easier:

从 iOS9 开始,它变得更容易了:

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


Or if you have a UINavigationController managing the view controllers, you could check its visibleViewControllerproperty instead.

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

回答by ma11hew28

Here's @progrmr's solution as a UIViewControllercategory:

这是@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

回答by vincentjames501

There are a couple of issues with the above solutions. If you are using, for example, a UISplitViewController, the master view will always return true for

上述解决方案存在几个问题。例如,如果您正在使用 a UISplitViewController,则主视图将始终为

if(viewController.isViewLoaded && viewController.view.window) {
    //Always true for master view in split view controller
}

Instead, take this simple approach which seems to work well in most, if not all cases:

取而代之的是,采用这种简单的方法,它似乎在大多数情况下(如果不是所有情况)都能很好地工作:

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

回答by Benjamin

For those of you looking for a Swift 2.2version of the answer:

对于那些正在寻找答案的Swift 2.2版本的人:

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

and Swift 3:

斯威夫特 3

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

回答by WeZZard

For over-full-screen or over-context modal presentation, "is visible" could mean it is on top of the view controller stack or just visible but covered by another view controller.

对于超全屏或超上下文模式呈现,“可见”可能意味着它位于视图控制器堆栈的顶部,或者只是可见但被另一个视图控制器覆盖。

To check if the view controller "is the top view controller" is quite different from "is visible", you should check the view controller's navigation controller's view controller stack.

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

I wrote a piece of code to solve this problem:

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

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

回答by executor21

You want to use the UITabBarController's selectedViewControllerproperty. All view controllers attached to a tab bar controller have a tabBarControllerproperty set, so you can, from within any of the view controllers' code:

您想使用UITabBarControllerselectedViewController属性。附加到标签栏控制器的所有视图控制器都有一个tabBarController属性集,因此您可以从任何视图控制器的代码中:

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

回答by Besi

I made a swift extension based on @progrmr's answer.

我根据@progrmr 的回答进行了快速扩展。

It allows you to easily check if a UIViewControlleris on screen like so:

它使您可以轻松检查UIViewController屏幕上是否显示 a ,如下所示:

if someViewController.isOnScreen {
    // Do stuff here
}

The extension:

扩展名:

//
//  UIViewControllerExtension.swift
//

import UIKit

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

回答by Chris Prince

For my purposes, in the context of a container view controller, I've found that

出于我的目的,在容器视图控制器的上下文中,我发现

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

works well.

效果很好。

回答by MrTristan

if you're utilizing a UINavigationController and also want to handle modal views, the following is what i use:

如果您正在使用 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
}

回答by wigging

The approach that I used for a modal presented view controller was to check the class of the presented controller. If the presented view controller was ViewController2then I would execute some code.

我用于模态呈现的视图控制器的方法是检查呈现的控制器的类。如果呈现的视图控制器是,ViewController2那么我将执行一些代码。

UIViewController *vc = [self presentedViewController];

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