Saya memiliki aplikasi tab bar, dengan banyak tampilan. Apakah ada cara untuk mengetahui apakah suatu UIViewController
saat ini terlihat dari dalam UIViewController
? (mencari properti)
Saya memiliki aplikasi tab bar, dengan banyak tampilan. Apakah ada cara untuk mengetahui apakah suatu UIViewController
saat ini terlihat dari dalam UIViewController
? (mencari properti)
Jawaban:
Properti jendela tampilan adalah nihil jika tampilan saat ini terlihat, jadi periksa tampilan utama di pengontrol tampilan:
Menjalankan metode tampilan menyebabkan tampilan memuat (jika tidak dimuat) yang tidak perlu dan mungkin tidak diinginkan. Akan lebih baik untuk memeriksa dulu untuk melihat apakah sudah dimuat. Saya telah menambahkan panggilan ke isViewLoaded untuk menghindari masalah ini.
if (viewController.isViewLoaded && viewController.view.window) {
// viewController is visible
}
Sejak iOS9 menjadi lebih mudah:
if viewController.viewIfLoaded?.window != nil {
// viewController is visible
}
Atau jika Anda memiliki UINavigationController yang mengelola pengontrol tampilan, Anda dapat memeriksa properti visibleViewControllernya .
topViewController
.
Inilah solusi @ progrmr sebagai UIViewController
kategori:
// 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
Ada beberapa masalah dengan solusi di atas. Jika Anda menggunakan, misalnya, a UISplitViewController
, tampilan master akan selalu benar untuk
if(viewController.isViewLoaded && viewController.view.window) {
//Always true for master view in split view controller
}
Sebagai gantinya, ambil pendekatan sederhana ini yang tampaknya bekerja dengan baik di sebagian besar, jika tidak semua kasus:
- (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;
}
Bagi Anda yang mencari versi Swift 2.2 dari jawabannya:
if self.isViewLoaded() && (self.view.window != nil) {
// viewController is visible
}
dan Swift 3 :
if self.isViewLoaded && (self.view.window != nil) {
// viewController is visible
}
Untuk presentasi moda over-layar penuh atau over-konteks, "terlihat" bisa berarti itu di atas tumpukan pengontrol tampilan atau hanya terlihat tetapi ditutupi oleh pengontrol tampilan lain.
Untuk memeriksa apakah pengontrol tampilan "adalah pengontrol tampilan atas" sangat berbeda dari "terlihat", Anda harus memeriksa tumpukan pengendali tampilan pengendali navigasi pengendali view controller.
Saya menulis sepotong kode untuk mengatasi masalah ini:
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
adalah properti sejak Swift 3.0.
Anda ingin menggunakan properti UITabBarController
's selectedViewController
. Semua pengontrol tampilan yang terlampir pada pengontrol bilah tab memiliki tabBarController
properti yang diatur, jadi Anda bisa, dari dalam kode pengontrol tampilan apa pun:
if([[[self tabBarController] selectedViewController] isEqual:self]){
//we're in the active controller
}else{
//we are not
}
((UINavigationController *)self.tabBarController.selectedViewController).visibleViewController
Saya membuat ekstensi cepat berdasarkan jawaban @ progrmr.
Ini memungkinkan Anda untuk dengan mudah memeriksa apakah UIViewController
ada di layar seperti:
if someViewController.isOnScreen {
// Do stuff here
}
Ekstensi:
//
// UIViewControllerExtension.swift
//
import UIKit
extension UIViewController{
var isOnScreen: Bool{
return self.isViewLoaded() && view.window != nil
}
}
Untuk tujuan saya, dalam konteks pengontrol tampilan wadah, saya telah menemukan itu
- (BOOL)isVisible {
return (self.isViewLoaded && self.view.window && self.parentViewController != nil);
}
bekerja dengan baik.
jika Anda menggunakan UINavigationController dan juga ingin menangani tampilan modal, berikut ini yang saya gunakan:
#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
}
Pendekatan yang saya gunakan untuk modal yang disajikan view controller adalah untuk memeriksa kelas controller yang disajikan. Jika controller tampilan yang disajikan adalah ViewController2
maka saya akan menjalankan beberapa kode.
UIViewController *vc = [self presentedViewController];
if ([vc isKindOfClass:[ViewController2 class]]) {
NSLog(@"this is VC2");
}
Saya menemukan fungsi tersebut di 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);
Mungkin fungsi di atas bisa mendeteksi ViewController
muncul atau tidak.
XCode 6.4, untuk iOS 8.4, ARC diaktifkan
Jelas banyak cara untuk melakukannya. Salah satu yang telah bekerja untuk saya adalah sebagai berikut ...
@property(nonatomic, readonly, getter=isKeyWindow) BOOL keyWindow
Ini dapat digunakan di pengontrol tampilan apa pun dengan cara berikut,
[self.view.window isKeyWindow]
Jika Anda memanggil properti ini di dalam -(void)viewDidLoad
Anda mendapatkan 0, maka jika Anda memanggil ini setelah -(void)viewDidAppear:(BOOL)animated
Anda mendapatkan 1.
Semoga ini bisa membantu seseorang. Terima kasih! Bersulang.
Jika Anda menggunakan pengontrol navigasi dan hanya ingin tahu apakah Anda berada di pengontrol aktif dan teratas , maka gunakan:
if navigationController?.topViewController == self {
// Do something
}
Jawaban ini didasarkan pada komentar @mattdipasquale .
Jika Anda memiliki skenario yang lebih rumit, lihat jawaban lain di atas.
Anda dapat memeriksanya menurut window
properti
if(viewController.view.window){
// view visible
}else{
// no visible
}
Saya memerlukan ini untuk memeriksa apakah view controller adalah controller yang dilihat saat ini, saya melakukannya dengan memeriksa apakah ada controller tampilan yang disajikan atau didorong melalui navigator, saya mempostingnya jika ada yang membutuhkan solusi seperti itu:
if presentedViewController != nil || navigationController?.topViewController != self {
//Viewcontroller isn't viewed
}else{
// Now your viewcontroller is being viewed
}
Saya menggunakan ekstensi kecil ini di Swift 5 , yang membuatnya sederhana dan mudah untuk memeriksa objek apa pun yang merupakan anggota UIView .
extension UIView {
var isVisible: Bool {
guard let _ = self.window else {
return false
}
return true
}
}
Kemudian, saya hanya menggunakannya sebagai pernyataan ...
if myView.isVisible {
// do something
}
Saya harap ini membantu! :)