私は多くのビューを持つタブバーアプリケーションを持っています。特定のUIViewController
が現在UIViewController
内から見えるかどうかを知る方法はありますか? (物件を探しています)
ビューが現在表示されている場合、ビューの 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
}
これは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
上記の解決策にはいくつかの問題があります。たとえば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;
}
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
}
あなたはUITabBarController
のselectedViewController
プロパティを使いたいのです。 Tab Bar Controllerに接続されているすべてのView ControllerにはtabBarController
プロパティが設定されているので、どのView Controllerのコード内からでも使用できます。
if([[[self tabBarController] selectedViewController] isEqual:self]){
//we're in the active controller
}else{
//we are not
}
フルスクリーンまたはコンテキストを超えたモーダルプレゼンテーションの場合、「表示されている」とは、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
}
}
}
私は@ progrmrの答えに基づいてSwift拡張を作りました。
UIViewController
が画面に表示されているかどうかを簡単に確認できます。
if someViewController.isOnScreen {
// Do stuff here
}
拡張子:
//
// UIViewControllerExtension.Swift
//
import UIKit
extension UIViewController{
var isOnScreen: Bool{
return self.isViewLoaded() && view.window != nil
}
}
私の目的のためには、コンテナView Controllerのコンテキストでは、
- (BOOL)isVisible {
return (self.isViewLoaded && self.view.window && self.parentViewController != nil);
}
うまくいきます。
これらの関数は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
が出現したかどうかを検出することができます。
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
}
ナビゲーションコントローラを使用していて、 active および topmost のコントローラにいるかどうかだけを知りたい場合は、次のようにします。
if navigationController?.topViewController == self {
// Do something
}
この回答は @mattdipasquale のコメントに基づいています。
もっと複雑なシナリオがある場合は、上記の他の答えを参照してください。
私がモーダルの提示型ビューコントローラに使用したアプローチは、提示されたコントローラのクラスをチェックすることでした。表示されているView ControllerがViewController2
であれば、いくつかのコードを実行します。
UIViewController *vc = [self presentedViewController];
if ([vc isKindOfClass:[ViewController2 class]]) {
NSLog(@"this is VC2");
}
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になります。
これが誰かに役立つことを願っています。ありがとうございます。乾杯。
window
プロパティで確認できます
if(viewController.view.window){
// view visible
}else{
// no visible
}
View Controllerが現在表示されているコントローラかどうかを確認するためにこれが必要でした。表示されているView Controllerがあるか、ナビゲータを介してプッシュされたかを確認しました。
if presentedViewController != nil || navigationController?.topViewController != self {
//Viewcontroller isn't viewed
}else{
// Now your viewcontroller is being viewed
}