15 ответов:
вид окне Свойства не равно нулю, если вид в настоящее время виден, поэтому проверьте основной вид в контроллере вида:
[EDIT] вызов view метод вызывает загрузку представления (если оно не загружено), что является ненужным и может быть нежелательным. Было бы лучше сначала проверить, если он уже загружен. Я добавил вызов isViewLoaded, чтобы избежать этой проблемы.
if (viewController.isViewLoaded && viewController.view.window) { // viewController is visible }или если вы у UINavigationController, управляющего контроллерами представления, вы можете проверить его visibleViewController свойство вместо этого.
кроме того, в Swift на iOS 9 (или более поздней версии):
if viewController.viewIfLoaded?.window != nil { // viewController is visible }
вот решение @ 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
есть несколько проблем с вышеуказанными решениями. Если вы используете, например,
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' sselectedViewControllerсобственность. Все контроллеры вида, подключенные к контроллеру панели вкладок, имеютtabBarControllerнабор свойств, так что вы можете, из любого кода контроллера вида:if([[[self tabBarController] selectedViewController] isEqual:self]){ //we're in the active controller }else{ //we are not }
Для над-полноэкранного или над-контекстного модального представления "виден" может означать, что он находится поверх стека контроллера вида или просто виден, но покрыт другим контроллером вида.
чтобы проверить, что контроллер вида "является контроллером вида сверху" сильно отличается от "виден", вы должны проверить стек контроллера вида контроллера навигации контроллера вида.
Я написал кусок кода, чтобы решить эту проблему:
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.
Это позволяет легко проверить, если
UIViewControllerна экране, например:if someViewController.isOnScreen { // Do stuff here }расширения:
// // UIViewControllerExtension.swift // import UIKit extension UIViewController{ var isOnScreen: Bool{ return self.isViewLoaded() && view.window != nil } }
для моих целей, в контексте контроллера представления контейнера, я обнаружил, что
- (BOOL)isVisible { return (self.isViewLoaded && self.view.window && self.parentViewController != nil); }работает хорошо.
Если вы используете 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появляется или нет.
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.надеюсь, это кому-то поможет. Спасибо! Овации.
вы можете проверить это с помощью
windowсвойстваif(viewController.view.window){ // view visible }else{ // no visible }
подход, который я использовал для модального представленного контроллера вида, состоял в том, чтобы проверить класс представленного контроллера. Если представленный контроллер вида был
ViewController2тогда я бы выполнил некоторый код.UIViewController *vc = [self presentedViewController]; if ([vc isKindOfClass:[ViewController2 class]]) { NSLog(@"this is VC2"); }
Если вы используете навигационный контроллер и просто хотите знать, находитесь ли вы в активный и верхний контроллер, а затем использовать:
if navigationController?.topViewController == self { // Do something }этот ответ основан на @mattdipasqualeкомментарий.
Если у вас есть более сложный сценарий, см. другие ответы выше.
Мне нужно было это, чтобы проверить, является ли контроллер вида текущим контроллером просмотра, я сделал это, проверив, есть ли какой-либо представленный контроллер вида или проталкивается через навигатор, я публикую его в случае, если кому-то нужно такое решение:
if presentedViewController != nil || navigationController?.topViewController != self { //Viewcontroller isn't viewed }else{ // Now your viewcontroller is being viewed }
Comments