У мене є додаток на панелі вкладок з багатьма переглядами. Чи є спосіб дізнатись, чи певна UIViewController
зараз видно зсередини UIViewController
? (шукаю нерухомість)
У мене є додаток на панелі вкладок з багатьма переглядами. Чи є спосіб дізнатись, чи певна UIViewController
зараз видно зсередини UIViewController
? (шукаю нерухомість)
Відповіді:
Властивість вікна перегляду є нульовою, якщо подання переглядається в даний час, тому перевірте головний вигляд у контролері подання:
Викликання методу перегляду призводить до завантаження подання (якщо воно не завантажене), що є непотрібним і може бути небажаним. Було б краще перевірити спочатку, щоб перевірити, чи він уже завантажений. Я додав дзвінок до isViewLoaded, щоб уникнути цієї проблеми.
if (viewController.isViewLoaded && viewController.view.window) {
// viewController is visible
}
З iOS9 стало простіше:
if viewController.viewIfLoaded?.window != nil {
// viewController is visible
}
Або якщо у вас є UINavigationController, що управляє контролерами перегляду, ви можете перевірити його властивість видимого ViewViewController .
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
З вищезазначеними рішеннями існує пара питань. Якщо ви використовуєте, наприклад, a 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
}
і Swift 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
«S selectedViewController
власності. Усі контролери перегляду, приєднані до контролера панелі вкладок, мають tabBarController
набір властивостей, тому ви можете з будь-якого коду контролерів перегляду:
if([[[self tabBarController] selectedViewController] isEqual:self]){
//we're in the active controller
}else{
//we are not
}
((UINavigationController *)self.tabBarController.selectedViewController).visibleViewController
Я зробив швидке розширення на основі відповіді @ 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
}
Підхід, який я використовував для модального представленого контролера перегляду, полягав у тому, щоб перевірити клас представленого контролера. Якби представлений контролер перегляду був, 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
}
Я використовую це невелике розширення в Swift 5 , що дозволяє легко і легко перевіряти наявність будь-якого об'єкта, що є членом UIView .
extension UIView {
var isVisible: Bool {
guard let _ = self.window else {
return false
}
return true
}
}
Тоді я просто використовую це як просту перевірку заяви ...
if myView.isVisible {
// do something
}
Я сподіваюся, що це допомагає! :)