Ich habe eine Tab-Leisten-Anwendung mit vielen Ansichten. Gibt es eine Möglichkeit zu wissen, ob eine bestimmte UIViewController
Person derzeit in der UIViewController
Umgebung sichtbar ist ? (auf der Suche nach einer Immobilie)
Ich habe eine Tab-Leisten-Anwendung mit vielen Ansichten. Gibt es eine Möglichkeit zu wissen, ob eine bestimmte UIViewController
Person derzeit in der UIViewController
Umgebung sichtbar ist ? (auf der Suche nach einer Immobilie)
Antworten:
Die Fenstereigenschaft der Ansicht ist nicht Null, wenn eine Ansicht derzeit sichtbar ist. Überprüfen Sie daher die Hauptansicht im Ansichts-Controller:
Durch Aufrufen der Ansichtsmethode wird die Ansicht geladen (sofern sie nicht geladen ist), was nicht erforderlich und möglicherweise unerwünscht ist. Es ist besser, zuerst zu überprüfen, ob es bereits geladen ist. Ich habe den Aufruf von isViewLoaded hinzugefügt, um dieses Problem zu vermeiden.
if (viewController.isViewLoaded && viewController.view.window) {
// viewController is visible
}
Seit iOS9 ist es einfacher geworden:
if viewController.viewIfLoaded?.window != nil {
// viewController is visible
}
Wenn Sie einen UINavigationController haben, der die Ansichtscontroller verwaltet, können Sie stattdessen die Eigenschaft visibleViewController überprüfen .
topViewController
.
Hier ist die Lösung von @progrmr als UIViewController
Kategorie:
// 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
Bei den oben genannten Lösungen gibt es einige Probleme. Wenn Sie beispielsweise a verwenden UISplitViewController
, gibt die Masteransicht immer true für zurück
if(viewController.isViewLoaded && viewController.view.window) {
//Always true for master view in split view controller
}
Verwenden Sie stattdessen diesen einfachen Ansatz, der in den meisten, wenn nicht allen Fällen gut zu funktionieren scheint:
- (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;
}
Für diejenigen unter Ihnen, die nach einer Swift 2.2- Version der Antwort suchen :
if self.isViewLoaded() && (self.view.window != nil) {
// viewController is visible
}
und Swift 3 :
if self.isViewLoaded && (self.view.window != nil) {
// viewController is visible
}
Bei einer modalen Darstellung im Vollbildmodus oder im Kontext kann "sichtbar" bedeuten, dass sie sich über dem Stapel des Ansichtscontrollers befindet oder nur sichtbar ist, aber von einem anderen Ansichtscontroller abgedeckt wird.
Um zu überprüfen, ob der Ansichts-Controller "der Draufsicht-Controller ist" sich stark von "sichtbar" unterscheidet, sollten Sie den Ansichts-Controller-Stapel des Navigations-Controllers des Ansichts-Controllers überprüfen.
Ich habe einen Code geschrieben, um dieses Problem zu lösen:
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
ist eine Eigenschaft seit Swift 3.0.
Sie möchten die verwenden UITabBarController
‚s - selectedViewController
Eigenschaft. Alle an einen Registerkarten-Controller angehängten Ansichts-Controller verfügen über einen tabBarController
Eigenschaftssatz, sodass Sie in jedem Code der Ansichts-Controller Folgendes tun können:
if([[[self tabBarController] selectedViewController] isEqual:self]){
//we're in the active controller
}else{
//we are not
}
((UINavigationController *)self.tabBarController.selectedViewController).visibleViewController
Ich habe eine schnelle Erweiterung basierend auf der Antwort von @progrmr vorgenommen.
Damit können Sie einfach überprüfen, ob a wie UIViewController
folgt auf dem Bildschirm angezeigt wird:
if someViewController.isOnScreen {
// Do stuff here
}
Die Erweiterung:
//
// UIViewControllerExtension.swift
//
import UIKit
extension UIViewController{
var isOnScreen: Bool{
return self.isViewLoaded() && view.window != nil
}
}
Für meine Zwecke habe ich das im Kontext eines Container View Controllers gefunden
- (BOOL)isVisible {
return (self.isViewLoaded && self.view.window && self.parentViewController != nil);
}
funktioniert gut.
Wenn Sie einen UINavigationController verwenden und auch modale Ansichten verarbeiten möchten, verwende ich Folgendes:
#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
}
Der Ansatz, den ich für einen modalen Controller für präsentierte Ansichten verwendet habe, bestand darin, die Klasse des präsentierten Controllers zu überprüfen. Wenn der vorgestellte View Controller ViewController2
wäre, würde ich Code ausführen.
UIViewController *vc = [self presentedViewController];
if ([vc isKindOfClass:[ViewController2 class]]) {
NSLog(@"this is VC2");
}
Ich habe diese Funktion in gefunden 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);
Möglicherweise können die oben genannten Funktionen erkennen, ob das angezeigt ViewController
wird oder nicht.
XCode 6.4, für iOS 8.4, ARC aktiviert
Offensichtlich viele Möglichkeiten, dies zu tun. Derjenige, der für mich gearbeitet hat, ist der folgende ...
@property(nonatomic, readonly, getter=isKeyWindow) BOOL keyWindow
Dies kann in jedem View Controller auf folgende Weise verwendet werden:
[self.view.window isKeyWindow]
Wenn Sie diese Eigenschaft in aufrufen, erhalten -(void)viewDidLoad
Sie 0, und wenn Sie dies aufrufen, nachdem -(void)viewDidAppear:(BOOL)animated
Sie 1 erhalten haben.
Hoffe das hilft jemandem. Vielen Dank! Prost.
Wenn Sie einen Navigationscontroller verwenden und nur wissen möchten, ob Sie sich im aktiven und obersten Controller befinden, verwenden Sie:
if navigationController?.topViewController == self {
// Do something
}
Diese Antwort basiert auf dem Kommentar von @mattdipasquale .
Wenn Sie ein komplizierteres Szenario haben, lesen Sie die anderen Antworten oben.
Sie können es durch window
Eigenschaft überprüfen
if(viewController.view.window){
// view visible
}else{
// no visible
}
Ich brauchte dies, um zu überprüfen, ob der Ansichts-Controller der aktuell angezeigte Controller ist. Ich habe dies getan, indem ich überprüft habe, ob ein Ansichts-Controller angezeigt oder durch den Navigator geschoben wurde. Ich poste ihn, falls jemand eine solche Lösung benötigt:
if presentedViewController != nil || navigationController?.topViewController != self {
//Viewcontroller isn't viewed
}else{
// Now your viewcontroller is being viewed
}
Ich verwende diese kleine Erweiterung in Swift 5 , mit der es einfach und leicht ist, nach Objekten zu suchen , die Mitglied von UIView sind .
extension UIView {
var isVisible: Bool {
guard let _ = self.window else {
return false
}
return true
}
}
Dann benutze ich es einfach als einfache if-Anweisungsprüfung ...
if myView.isVisible {
// do something
}
Ich hoffe, es hilft! :) :)