web-dev-qa-db-ja.com

UIViewControllerビューが表示されているかどうかを確認する方法

私は多くのビューを持つタブバーアプリケーションを持っています。特定のUIViewControllerが現在UIViewController内から見えるかどうかを知る方法はありますか? (物件を探しています)

517
Rob Bonner

ビューが現在表示されている場合、ビューの windowプロパティ はnil以外であるため、ビューコントローラのメインビューを確認してください。

view メソッドを呼び出すと、ビューがロードされます(ロードされていない場合)。これは不要で、望ましくない場合があります。それが既にロードされているかどうかを確認するために最初にチェックする方が良いでしょう。この問題を回避するために、isViewLoadedへの呼び出しを追加しました。

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

あるいは、View Controllerを管理するUINavigationControllerがある場合は、代わりに visibleViewController プロパティをチェックすることもできます。

また、iOS 9以降のSwiftでは、次のようになります。

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

これはUIViewControllerカテゴリとしての@ progrmrの解決策です。

// 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
88
ma11hew28

上記の解決策にはいくつかの問題があります。たとえばUISplitViewControllerを使用している場合、マスタービューは常に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;
}
44
vincentjames501

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

あなたはUITabBarControllerselectedViewControllerプロパティを使いたいのです。 Tab Bar Controllerに接続されているすべてのView ControllerにはtabBarControllerプロパティが設定されているので、どのView Controllerのコード内からでも使用できます。

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

フルスクリーンまたはコンテキストを超えたモーダルプレゼンテーションの場合、「表示されている」とは、View Controllerスタックの一番上にあるか、表示されているが別のView Controllerによって覆われていることを意味します。

View Controllerが「最上位のView Controller」であるかどうか「is visible」とまったく異なるかどうかを確認するには、View ControllerのNavigation ControllerのView Controllerスタックを確認する必要があります。

この問題を解決するためのコードを書いた。

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

私は@ progrmrの答えに基づいてSwift拡張を作りました。

UIViewControllerが画面に表示されているかどうかを簡単に確認できます。

if someViewController.isOnScreen {
    // Do stuff here
}

拡張子:

//
//  UIViewControllerExtension.Swift
//

import UIKit

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

私の目的のためには、コンテナView Controllerのコンテキストでは、

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

うまくいきます。

7
Chris Prince

これらの関数は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が出現したかどうかを検出することができます。

3
AechoLiu

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

ナビゲーションコントローラを使用していて、 active および topmost のコントローラにいるかどうかだけを知りたい場合は、次のようにします。

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

この回答は @mattdipasquale のコメントに基づいています。

もっと複雑なシナリオがある場合は、上記の他の答えを参照してください。

3
phatmann

私がモーダルの提示型ビューコントローラに使用したアプローチは、提示されたコントローラのクラスをチェックすることでした。表示されているView ControllerがViewController2であれば、いくつかのコードを実行します。

UIViewController *vc = [self presentedViewController];

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

XCode 6.4、iOS 8.4、ARC対応

明らかにそれを行う方法はたくさんあります。私のために働いているものは以下の通りです...

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

これは、どのView Controllerでも次のように使用できます。

[self.view.window isKeyWindow]

-(void)viewDidLoadでこのプロパティを呼び出すと0になり、-(void)viewDidAppear:(BOOL)animatedの後にこのプロパティを呼び出すと1になります。

これが誰かに役立つことを願っています。ありがとうございます。乾杯。

3
serge-k

windowプロパティで確認できます

if(viewController.view.window){

// view visible

}else{

// no visible

}
2
Saad Ur Rehman

View Controllerが現在表示されているコントローラかどうかを確認するためにこれが必要でした。表示されているView Controllerがあるか、ナビゲータを介してプッシュされたかを確認しました。

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