ฉันมีแอปพลิเคชันแถบแท็บที่มีมุมมองมากมาย มีวิธีที่จะรู้ได้หรือไม่ว่าในUIViewControllerปัจจุบันนั้นสามารถมองเห็นได้จากภายในUIViewController? (มองหาอสังหาริมทรัพย์)
ฉันมีแอปพลิเคชันแถบแท็บที่มีมุมมองมากมาย มีวิธีที่จะรู้ได้หรือไม่ว่าในUIViewControllerปัจจุบันนั้นสามารถมองเห็นได้จากภายในUIViewController? (มองหาอสังหาริมทรัพย์)
คำตอบ:
คุณสมบัติหน้าต่างของมุมมองไม่เป็นศูนย์ถ้ามองเห็นได้ในขณะนี้ดังนั้นให้ตรวจสอบมุมมองหลักในตัวควบคุมมุมมอง:
การเรียกใช้เมธอดviewทำให้มุมมองโหลด (หากไม่ได้โหลด) ซึ่งไม่จำเป็นและอาจไม่พึงปรารถนา มันจะเป็นการดีกว่าที่จะตรวจสอบก่อนเพื่อดูว่ามันโหลดแล้ว ฉันได้เพิ่มการเรียกไปยัง isViewLoaded เพื่อหลีกเลี่ยงปัญหานี้
if (viewController.isViewLoaded && viewController.view.window) {
    // viewController is visible
}ตั้งแต่ iOS9 มันง่ายขึ้น:
if viewController.viewIfLoaded?.window != nil {
    // viewController is visible
}หรือถ้าคุณมี UINavigationController จัดการมุมมองตัวควบคุมคุณสามารถตรวจสอบคุณสมบัติvisibleViewController
topViewControllerในกรณีที่ใช้
                    นี่คือโซลูชันของ @ 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มุมมองหลักจะส่งกลับค่าจริงเสมอ
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
}และรวดเร็ว 3 :
if self.isViewLoaded && (self.view.window != nil) {
         // viewController is visible
}สำหรับการนำเสนอแบบเต็มหน้าจอหรือมากกว่าบริบทคำว่า "มองเห็นได้" อาจหมายถึงมันอยู่ด้านบนของตัวควบคุมมุมมองสแต็กหรือมองเห็นได้ แต่ครอบคลุมโดยตัวควบคุมมุมมองอื่น
ในการตรวจสอบว่าตัวควบคุมมุมมอง "เป็นตัวควบคุมมุมมองด้านบน" ค่อนข้างแตกต่างจาก "มองเห็นได้" คุณควรตรวจสอบสแตกตัวควบคุมมุมมองของตัวควบคุมการนำทางของตัวควบคุมมุมมอง
ฉันเขียนโค้ดเพื่อแก้ปัญหานี้:
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เป็นคุณสมบัติตั้งแต่ Swift 3.0
                    คุณต้องการที่จะใช้UITabBarControllerของselectedViewControllerสถานที่ให้บริการ ตัวควบคุมมุมมองทั้งหมดที่แนบกับตัวควบคุมแถบแท็บมีtabBarControllerชุดคุณสมบัติดังนั้นคุณสามารถทำได้จากภายในรหัสตัวควบคุมมุมมองใด ๆ :
if([[[self tabBarController] selectedViewController] isEqual:self]){
     //we're in the active controller
}else{
     //we are not
}((UINavigationController *)self.tabBarController.selectedViewController).visibleViewController
                    ฉันสร้างส่วนขยายอย่างรวดเร็วตามคำตอบของ @ progrmr
มันช่วยให้คุณตรวจสอบได้ง่ายว่า a 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
}วิธีการที่ฉันใช้สำหรับตัวควบคุมมุมมองการนำเสนอ modal คือการตรวจสอบคลาสของตัวควบคุมที่นำเสนอ หากตัวควบคุมมุมมองที่นำเสนอViewController2นั้นฉันจะรันรหัสบางอย่าง
UIViewController *vc = [self presentedViewController];
if ([vc isKindOfClass:[ViewController2 class]]) {
    NSLog(@"this is VC2");
}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
หวังว่านี่จะช่วยใครซักคน ขอบคุณ! ไชโย
หากคุณใช้ตัวควบคุมการนำทางและต้องการทราบว่าคุณอยู่ในตัวควบคุมที่ใช้งานอยู่และระดับสูงสุดให้ใช้:
if navigationController?.topViewController == self {
    // Do something
}คำตอบนี้ขึ้นอยู่กับความคิดเห็นของ@mattdipasquale
หากคุณมีสถานการณ์ที่ซับซ้อนขึ้นให้ดูคำตอบอื่น ๆ ด้านบน
คุณสามารถตรวจสอบได้ตามwindowคุณสมบัติ
if(viewController.view.window){
// view visible
}else{
// no visible
}ฉันต้องการสิ่งนี้เพื่อตรวจสอบว่าตัวควบคุมมุมมองเป็นตัวควบคุมที่ดูอยู่ในปัจจุบันหรือไม่ฉันผ่านการตรวจสอบว่ามีตัวควบคุมมุมมองที่แสดงหรือผลักผ่านตัวนำทางฉันกำลังโพสต์ไว้ในกรณีที่ใครก็ตามต้องการโซลูชันดังกล่าว
if presentedViewController != nil || navigationController?.topViewController != self {
      //Viewcontroller isn't viewed
}else{
     // Now your viewcontroller is being viewed 
}ผมใช้นามสกุลนี้มีขนาดเล็กในสวิฟท์ 5ซึ่งทำให้มันง่ายและง่ายต่อการตรวจสอบวัตถุใด ๆ ที่เป็นสมาชิกของUIView
extension UIView {
    var isVisible: Bool {
        guard let _ = self.window else {
            return false
        }
        return true
    }
}จากนั้นฉันก็ใช้มันเป็นคำสั่งง่ายๆถ้าตรวจสอบ ...
if myView.isVisible {
    // do something
}ฉันหวังว่ามันจะช่วย! :)