ios - queda - iphone bateria litio
Compruebe si el controlador de vista se presenta de forma modal o empujado en una pila de navegaciĆ³n (14)
auto.navigationController! = nil significaría que está en una pila de navegación.
Para manejar el caso en el que se empuja el controlador de vista actual mientras el controlador de navegación se presenta de manera modal, he agregado algunas líneas de código para verificar si el controlador de vista actual es el controlador raíz en la pila de navegación.
extension UIViewController{
func isModal() -> Bool {
if let navigationController = self.navigationController{
if navigationController.viewControllers.first != self{
return false
}
}
if self.presentingViewController != nil {
return true
}
if self.navigationController?.presentingViewController?.presentedViewController == self.navigationController {
return true
}
if self.tabBarController?.presentingViewController is UITabBarController {
return true
}
return false
}
}
¿Cómo puedo, en mi código de controlador de vista, diferenciar entre:
- presentado de forma modal
- empujado en la pila de navegación
Both presentingViewController
y isMovingToParentViewController
son YES
en ambos casos, por lo que no son muy útiles.
Lo que complica las cosas es que mi controlador de vista padre a veces es modal, en el que se empuja el controlador de vista comprobado.
Resulta que mi problema es que incorporo mi HtmlViewController
en un UINavigationController
que luego se presenta. Es por eso que mis propios intentos y las buenas respuestas a continuación no estaban funcionando.
HtmlViewController* termsViewController = [[HtmlViewController alloc] initWithDictionary:dictionary];
UINavigationController* modalViewController;
modalViewController = [[UINavigationController alloc] initWithRootViewController:termsViewController];
modalViewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[self presentViewController:modalViewController
animated:YES
completion:nil];
Creo que será mejor que le diga a mi controlador de vista cuándo es modal, en lugar de tratar de determinarlo.
Como muchas personas aquí sugieren, que los métodos de "verificación" no funcionan bien para todos los casos, en mi proyecto he encontrado una solución para administrarlo manualmente. El punto es que generalmente administramos la presentación por nuestra cuenta, esto no es lo que ocurre detrás de la escena y debemos hacer una introspección.
Archivo DEViewController.h
:
#import <UIKit/UIKit.h>
// it is a base class for all view controllers within a project
@interface DEViewController : UIViewController
// specify a way viewcontroller, is presented by another viewcontroller
// the presented view controller should manually assign the value to it
typedef NS_ENUM(NSUInteger, SSViewControllerPresentationMethod) {
SSViewControllerPresentationMethodUnspecified = 0,
SSViewControllerPresentationMethodPush,
SSViewControllerPresentationMethodModal,
};
@property (nonatomic) SSViewControllerPresentationMethod viewControllerPresentationMethod;
// other properties/methods...
@end
Las presentaciones ahora se pueden administrar de esta manera:
empujado en la pila de navegación:
// DETestViewController inherits from DEViewController
DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodPush;
[self.navigationController pushViewController:vc animated:YES];
presentado modalmente con navegación:
DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodModal;
UINavigationController *nav = [[UINavigationController alloc]
initWithRootViewController:vc];
[self presentViewController:nav animated:YES completion:nil];
presentado de forma modal
DETestViewController *vc = [DETestViewController new];
vc.viewControllerPresentationMethod = SSViewControllerPresentationMethodModal;
[self presentViewController:vc animated:YES completion:nil];
Además, en DEViewController
podríamos agregar una alternativa a "verificar" si la propiedad antes mencionada es igual a SSViewControllerPresentationMethodUnspecified
:
- (BOOL)isViewControllerPushed
{
if (self.viewControllerPresentationMethod != SSViewControllerPresentationMethodUnspecified) {
return (BOOL)(self.viewControllerPresentationMethod == SSViewControllerPresentationMethodPush);
}
else {
// fallback to default determination method
return (BOOL)self.navigationController.viewControllers.count > 1;
}
}
En Swift :
func isModal() -> Bool {
if self.presentingViewController != nil {
return true
} else if self.navigationController?.presentingViewController?.presentedViewController == self.navigationController {
return true
} else if self.tabBarController?.presentingViewController is UITabBarController {
return true
}
return false
}
Para alguien que se pregunta, Cómo decirle a ViewController que se está presentando
si A
presenta / empuja B
Definir una
enum
yproperty
enB
enum ViewPresentationStyle { case Push case Present } //and write property var vcPresentationStyle : ViewPresentationStyle = .Push //default value, considering that B is pushed
Ahora en el controlador de vista
A
, dile aB
si se está presentando / presionando asignandopresentationStyle
func presentBViewController() { let bViewController = B() bViewController.vcPresentationStyle = .Present //telling B that it is being presented self.presentViewController(bViewController, animated: true, completion: nil) }
Uso en el controlador de vista
B
override func viewDidLoad() { super.viewDidLoad() if self.vcPresentationStyle == .Present { //is being presented } else { //is being pushed } }
Para detectar que su controlador está presionado o no, utilice el código que se encuentra debajo en cualquier lugar que desee:
if ([[[self.parentViewController childViewControllers] firstObject] isKindOfClass:[self class]]) {
// Not pushed
}
else {
// Pushed
}
Espero que este código pueda ayudar a cualquiera ...
Si está utilizando ios 5.0 o posterior, utilice este código
-(BOOL)isPresented
{
if ([self isBeingPresented]) {
// being presented
return YES;
} else if ([self isMovingToParentViewController]) {
// being pushed
return NO;
} else {
// simply showing again because another VC was dismissed
return NO;
}
}
Suponiendo que todos los viewControllers que presente de forma modal estén incluidos en un nuevo navigationController (que siempre debe hacer de todos modos), puede agregar esta propiedad a su VC.
private var wasPushed: Bool {
guard let vc = navigationController?.viewControllers.first where vc == self else {
return true
}
return false
}
Tome con un grano de sal, no hizo la prueba.
- (BOOL)isModal {
if([self presentingViewController])
return YES;
if([[[self navigationController] presentingViewController] presentedViewController] == [self navigationController])
return YES;
if([[[self tabBarController] presentingViewController] isKindOfClass:[UITabBarController class]])
return YES;
return NO;
}
isBeingPresented
alto un método: isBeingPresented
.
isBeingPresented
es verdadero cuando el controlador de vista se presenta y es falso cuando se lo presiona.
- (void)viewWillAppear:(BOOL)animated {
[super viewWillAppear:animated];
if ([self isBeingPresented]) {
// being presented
} else if ([self isMovingToParentViewController]) {
// being pushed
} else {
// simply showing again because another VC was dismissed
}
}
self.navigationController != nil
significaría que está en una pila de navegación.
Swift 3
Aquí hay una solución que resuelve el problema mencionado con las respuestas anteriores, cuando isModal()
devuelve true
si UIViewController
está en una pila presentada de UINavigationController
.
extension UIViewController {
var isModal: Bool {
if let index = navigationController?.viewControllers.index(of: self), index > 0 {
return false
} else if presentingViewController != nil {
return true
} else if navigationController?.presentingViewController?.presentedViewController == navigationController {
return true
} else if tabBarController?.presentingViewController is UITabBarController {
return true
} else {
return false
}
}
}
A mí me funciona hasta ahora. Si hay algunas optimizaciones, por favor comparte.
Swift 4
var isModal: Bool {
return presentingViewController != nil ||
navigationController?.presentingViewController?.presentedViewController === navigationController ||
tabBarController?.presentingViewController is UITabBarController
}
id presentedController = self.navigationController.modalViewController;
if (presentedController) {
// Some view is Presented
} else {
// Some view is Pushed
}
Esto le permitirá saber si se presenta o empuja viewController
if let navigationController = self.navigationController, navigationController.isBeingPresented {
// being presented
}else{
// being pushed
}