2010-05-05 33 views

Trả lời

883

của xem window property là phi nil nếu một cái nhìn hiện rõ ràng, vì vậy kiểm tra giao diện chính trong bộ điều khiển xem:

[EDIT] Gọi phương pháp view gây ra xem để tải (nếu nó không được tải) mà là không cần thiết và có thể không mong muốn. Nó sẽ là tốt hơn để kiểm tra đầu tiên để xem nếu nó đã được nạp. Tôi đã thêm lệnh gọi isViewLoaded để tránh sự cố này.

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

Hoặc nếu bạn có một UINavigationController quản lý điều khiển xem, bạn có thể kiểm tra tài sản visibleViewController của nó để thay thế.

Ngoài ra, trong Swift trên iOS 9 (hoặc mới hơn):

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

Một vấn đề với thuộc tính visibleViewControllee của UINavigationController là trường hợp visibleViewController của bạn trình bày một bộ điều khiển xem phương thức. Trong trường hợp đó, khung nhìn phương thức trở thành visibleViewController, có thể không mong muốn. Làm thế nào bạn sẽ xử lý điều đó? – Moshe

+12

Điều này có thể hiển nhiên với mọi người, nhưng đối với tôi mã phải là self.isViewLoaded && self.view.window – JeffB6688

+0

Lưu ý rằng trong iOS 7, bộ điều khiển điều hướng không tải bộ điều khiển xem được đẩy vào bộ nhớ ngay lập tức. Điều này khác với iOS 6 nơi bạn có thể đẩy một bộ điều khiển xem và ngay lập tức thấy rằng navController.topViewController.isViewLoaded là đúng sự thật. – InkGolem

25

Bạn muốn sử dụng selectedViewController tài sản 's UITabBarController. Tất cả các bộ điều khiển xem gắn liền với một bộ điều khiển thanh tab có một bộ tabBarController bất động sản, vì vậy bạn có thể, từ bên trong bất kỳ mã các bộ điều khiển xem:

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

Điều này không hoạt động nếu bộ điều khiển chế độ xem được chứa bên trong bộ điều khiển điều hướng và bộ điều khiển đó được thêm vào bộ điều khiển thanh tab. Cuộc gọi đến selectedViewController sẽ trả về bộ điều khiển điều hướng chứ không phải bộ điều khiển xem hiện tại. –

+2

@AntonHolmberg trong trường hợp đó, có được bộ điều khiển xem hiển thị như thế này: '((UINavigationController *) self.tabBarController.selectedViewController). InvisibleViewController' – ma11hew28

+0

Hoặc thậm chí sử dụng thuộc tính 'self.tabBarController.selectedIndex' nếu chúng ta đã đi xa này. –

82

Dưới đây là @ giải pháp progrmr như một loại 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 
2

bạn có thể kiểm tra nó bằng cách window tài sản

if(viewController.view.window){ 

// view visible 

}else{ 

// no visible 

} 
3

nếu bạn đang sử dụng một UINavigationController và cũng muốn để xử lý chế độ xem phương thức, sau đây là những gì tôi sử dụng:

#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 
} 
+2

Tôi đã tìm thấy cách này đáng tin cậy hơn câu trả lời được chấp nhận, khi có sẵn bộ điều khiển điều hướng. Điều này có thể được rút ngắn thành: if ([self.navigationController.visibleViewController isKindOfClass: [self class]]) { – Darren

2

Cách tiếp cận mà tôi sử dụng cho trình điều khiển chế độ xem trình bày là kiểm tra lớp của bộ điều khiển được trình bày. Nếu trình điều khiển xem được trình bày là ViewController2 thì tôi sẽ thực thi một số mã.

UIViewController *vc = [self presentedViewController]; 

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

Có một số vấn đề với các giải pháp trên. Nếu bạn đang sử dụng, ví dụ, một UISplitViewController, quan điểm tổng thể sẽ luôn luôn trả đúng đối với

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

Thay vào đó, áp dụng cách này đơn giản mà dường như làm việc tốt trong hầu hết, nếu không phải tất cả các trường hợp:

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

Điều này vẫn đúng trong xCode 7.1.1? Master trong UISplitViewController của tôi trả về NO cho viewController.view.window. Tôi có thể làm điều gì đó sai, nhưng tôi khá chắc chắn đây là trường hợp. – SAHM

7

Đối với mục đích của tôi, trong bối cảnh của một bộ điều khiển xem container, tôi đã phát hiện ra rằng

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

hoạt động tốt.

17

Đối với bản trình bày toàn màn hình hoặc ngữ cảnh, "hiển thị" có thể có nghĩa là nó nằm trên ngăn xếp bộ điều khiển xem hoặc chỉ hiển thị nhưng được phủ bởi bộ điều khiển chế độ xem khác.

Để kiểm tra xem bộ điều khiển xem "là bộ điều khiển chế độ xem trên cùng" có khác với "hiển thị" hay không, bạn nên kiểm tra ngăn điều khiển bộ điều khiển của bộ điều khiển của bộ điều khiển xem.

Tôi đã viết một đoạn mã để giải quyết vấn đề này:

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

Bài đăng hay! FYI 'isViewLoaded' là thuộc tính kể từ Swift 3.0. –

11

tôi đã mở rộng nhanh chóng dựa trên câu trả lời @ progrmr của.

Nó cho phép bạn dễ dàng kiểm tra xem một UIViewController là trên màn hình như sau:

if someViewController.isOnScreen { 
    // Do stuff here 
} 

Phần mở rộng:

// 
// UIViewControllerExtension.swift 
// 

import UIKit 

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

tôi thấy những chức năng trong 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); 

Có thể các chức năng trên có thể phát hiện ViewController có xuất hiện hay không.

3

XCode 6.4, cho iOS 8.4, ARC bật

Rõ ràng là rất nhiều cách để thực hiện. Một trong đó đã làm việc đối với tôi là như sau ...

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

này có thể được sử dụng trong bất kỳ điều khiển xem theo cách sau,

[self.view.window isKeyWindow] 

Nếu bạn gọi khách sạn này trong -(void)viewDidLoad bạn nhận được 0 , sau đó nếu bạn gọi sau -(void)viewDidAppear:(BOOL)animated bạn nhận được 1.

Hy vọng điều này sẽ giúp ai đó. Cảm ơn! Chúc mừng.

33

Đối với những người bạn đang tìm kiếm một Swift 2.2 phiên bản của câu trả lời:

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

Swift 3:

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

Nếu bạn đang sử dụng một bộ điều khiển chuyển hướng và chỉ muốn để biết bạn có đang sử dụng bộ điều khiển hoạt độngtrên cùng, sau đó sử dụng:

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

Câu trả lời này dựa trên nhận xét của @mattdipasquale.

Nếu bạn có kịch bản phức tạp hơn, hãy xem các câu trả lời khác ở trên.

-2

Kể từ UIAlertController có nguồn gốc từ UIViewController bạn chỉ có thể sử dụng isBeingPresented

if (alertController.isBeingPresented) { 
    // alert is showing 
} 
Các vấn đề liên quan