Tôi có một ứng dụng thanh tab, với nhiều lượt xem. Có cách nào để biết nếu một cụ thể UIViewController
hiện đang được nhìn thấy từ bên trong UIViewController
? (tìm kiếm một tài sản)
Tôi có một ứng dụng thanh tab, với nhiều lượt xem. Có cách nào để biết nếu một cụ thể UIViewController
hiện đang được nhìn thấy từ bên trong UIViewController
? (tìm kiếm một tài sản)
Câu trả lời:
Thuộc tính cửa sổ của khung nhìn không phải là không nếu chế độ xem hiện đang hiển thị, vì vậy hãy kiểm tra chế độ xem chính trong trình điều khiển chế độ xem:
Gọi phương thức xem làm cho chế độ xem tải (nếu nó không được tải) không cần thiết và có thể không mong muốn. Nó sẽ tốt hơn để kiểm tra đầu tiên để xem nếu nó đã được tải. Tôi đã thêm cuộc gọi vào isViewLoaded để tránh sự cố này.
if (viewController.isViewLoaded && viewController.view.window) {
// viewController is visible
}
Kể từ iOS9, nó đã trở nên dễ dàng hơn:
if viewController.viewIfLoaded?.window != nil {
// viewController is visible
}
Hoặc nếu bạn có một UINavestionContaptor quản lý các bộ điều khiển xem, thay vào đó bạn có thể kiểm tra thuộc tính nhìn thấy của nó .
topViewController
.
Đây là giải pháp của @ progrmr như là một UIViewController
danh mục:
// 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
Có một vài vấn đề với các giải pháp trên. Nếu bạn đang sử dụng, ví dụ: a UISplitViewController
, chế độ xem chính sẽ luôn trả về đúng cho
if(viewController.isViewLoaded && viewController.view.window) {
//Always true for master view in split view controller
}
Thay vào đó, hãy thực hiện phương pháp đơn giản này có vẻ hoạt động tốt trong hầu hết các trường hợp, 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;
}
Đối với những bạn đang tìm kiếm một phiên bản Swift 2.2 của câu trả lời:
if self.isViewLoaded() && (self.view.window != nil) {
// viewController is visible
}
và Swift 3 :
if self.isViewLoaded && (self.view.window != nil) {
// viewController is visible
}
Đối với bản trình bày phương thức toàn màn hình hoặc trên toàn ngữ cảnh, "hiển thị" có thể có nghĩa là nó nằm trên đỉnh của trình điều khiển chế độ xem hoặc chỉ hiển thị nhưng được bao phủ bởi trình đ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" khác với "hiển thị", bạn nên kiểm tra ngăn xếp bộ điều khiển xem 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
}
}
}
isViewLoaded
là một tài sản kể từ Swift 3.0.
Bạn muốn sử dụng UITabBarController
's selectedViewController
tài sản. Tất cả các bộ điều khiển xem được gắn vào bộ điều khiển thanh tab đều có một tabBarController
bộ thuộc tính, do đó, bạn có thể, từ bất kỳ mã nào của bộ điều khiển xem:
if([[[self tabBarController] selectedViewController] isEqual:self]){
//we're in the active controller
}else{
//we are not
}
((UINavigationController *)self.tabBarController.selectedViewController).visibleViewController
Tôi đã thực hiện một phần mở rộng nhanh chóng dựa trên câu trả lời của @ progrmr.
Nó cho phép bạn dễ dàng kiểm tra nếu một UIViewController
trên màn hình như vậy:
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
}
}
Đối với mục đích của tôi, trong ngữ cảnh của trình điều khiển xem container, tôi đã thấy rằng
- (BOOL)isVisible {
return (self.isViewLoaded && self.view.window && self.parentViewController != nil);
}
hoạt động tốt
nếu bạn đang sử dụng một UINavestionControll và cũng muốn xử lý các chế độ xem theo chế độ, thì đâ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
}
Cách tiếp cận mà tôi đã sử dụng cho một trình điều khiển xem trình bày phương thức là kiểm tra lớp của trình điều khiển được trình bày. Nếu trình điều khiển khung nhìn được trình bày 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");
}
Tôi tìm thấy các 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.
XCode 6.4, cho iOS 8.4, bật ARC
Rõ ràng rất nhiều cách để làm điều đó. Người đã làm việc cho tôi là ...
@property(nonatomic, readonly, getter=isKeyWindow) BOOL keyWindow
Điều này có thể được sử dụng trong bất kỳ trình điều khiển xem theo cách sau,
[self.view.window isKeyWindow]
Nếu bạn gọi thuộc tính này trong -(void)viewDidLoad
bạn nhận được 0, thì nếu bạn gọi nó sau khi -(void)viewDidAppear:(BOOL)animated
bạn nhận được 1.
Hy vọng điều này sẽ giúp được ai đó. Cảm ơn! Chúc mừng.
Nếu bạn đang sử dụng bộ điều khiển điều hướng và chỉ muốn biết nếu bạn đang ở trong bộ điều khiển hoạt động và trên cùng , thì hãy 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ó một kịch bản phức tạp hơn, hãy xem các câu trả lời khác ở trên.
bạn có thể kiểm tra nó bằng window
tài sản
if(viewController.view.window){
// view visible
}else{
// no visible
}
Tôi cần điều này để kiểm tra xem bộ điều khiển xem có phải là bộ điều khiển đã xem hiện tại không, tôi đã thực hiện nó thông qua kiểm tra xem có bộ điều khiển xem nào được trình bày hay được đẩy qua bộ điều hướng hay không, tôi sẽ đăng nó trong trường hợp có ai cần giải pháp như vậy:
if presentedViewController != nil || navigationController?.topViewController != self {
//Viewcontroller isn't viewed
}else{
// Now your viewcontroller is being viewed
}
Tôi sử dụng tiện ích mở rộng nhỏ này trong Swift 5 , giúp đơn giản và dễ dàng kiểm tra mọi đối tượng là thành viên của UIView .
extension UIView {
var isVisible: Bool {
guard let _ = self.window else {
return false
}
return true
}
}
Sau đó, tôi chỉ sử dụng nó như một câu lệnh if đơn giản ...
if myView.isVisible {
// do something
}
Tôi hy vọng nó sẽ giúp! :)