presentViewController y muestra la barra de navegación


100

Tengo una jerarquía de controlador de vista y el controlador superior se muestra como modal y me gustaría saber cómo mostrar la barra de navegación cuando se usa

'UIViewController:presentViewController:viewControllerToPresent:animated:completion'

Los documentos para 'presentViewController: animated: completa:' nota:

'En iPhone y iPod touch, la vista presentada es siempre pantalla completa. En iPad, la presentación depende del valor de la propiedad modalPresentationStyle. '

Para 'modalPresentationStyle', los documentos dicen:

El estilo de presentación determina cómo se muestra en pantalla un controlador de vista presentado modalmente. En iPhone y iPod touch, los controladores de vista modal siempre se presentan en pantalla completa, pero en iPad hay varias opciones de presentación diferentes.

¿Hay alguna forma de asegurarse de que la barra de navegación esté visible debajo de la barra de estado una vez que se muestre el control de vista? ¿Debo interpretar el documento como, no tiene ninguna opción de iPhone / iPod y solo en iPad?

Anteriormente, estaba usando lo 'UIViewController:presentModalViewController:animated'que funcionaba bien, pero desde iOS 5.0, la API ha quedado obsoleta, así que voy a cambiar a la nueva.

Visualmente, lo que quiero hacer es que el nuevo controlador se deslice desde la parte inferior de la pantalla, como solía hacer la API anterior.

[actualizando con código]:

// My root level view:
UIViewController *vc = [[RootViewController alloc] 
                            initWithNibName:nil 
                            bundle:[NSBundle mainBundle]];
navController = [[UINavigationController alloc] initWithRootViewController:vc];        
....

// Within the RootViewController, Second view controller is created and added 
// to the hierarchy. It is this view controller that is responsible for 
// displaying the DetailView:
SecondTierViewController *t2controller = [[SecondTierViewController alloc] 
                                           initWithNibName:nil
                                           bundle:[NSBundle mainBundle]];

[self.navigationController pushViewController:t2controller animated:YES];

// Created by SecondTierViewController 
DetailViewController *controller = [[DetailViewController alloc] initWithNibName:nil                                                                                 
                                        bundle:[NSBundle mainBundle]];  

controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
controller.modalPresentationStyle = UIModalPresentationCurrentContext;

[self.navigationController presentViewController:controller 
                                        animated:YES 
                                        completion:nil];

Respuestas:


193

Es cierto que si presenta un controlador de vista de manera modal en el iPhone, siempre se presentará en pantalla completa sin importar cómo lo presente en el controlador de vista superior de un controlador de navegación o de cualquier otra forma. Pero siempre puede mostrar la barra de navegación con la siguiente forma de solución:

En lugar de presentar ese controlador de vista, presente modalmente un controlador de navegación con su controlador de vista raíz configurado como el controlador de vista que desea:

MyViewController *myViewController = [[MyViewController alloc] initWithNibName:nil bundle:nil];
UINavigationController *navigationController = 
    [[UINavigationController alloc] initWithRootViewController:myViewController];

//now present this navigation controller modally 
[self presentViewController:navigationController
                   animated:YES
                   completion:^{

                        }];

Debería ver una barra de navegación cuando su vista se presenta modalmente.


Eso es más o menos con lo que comencé. Pero la razón por la que no estoy usando 'presentModalViewController' es porque se considera una API obsoleta.
Jonas Gardner

esto es lo que se ha escrito en la clase UIViewController: // Mostrar otro controlador de vista como un hijo modal. Utiliza una transición de hoja vertical si está animada. Este método ha sido reemplazado por presentViewController: animated: completa: // Se DEPRECATED, planifique en consecuencia. - (void) presentModalViewController: (UIViewController *) modalViewController animado: (BOOL) animado; así que simplemente llame al nuevo método y pase nil para completar y debería estar bien.
Manish Ahuja

Gran respuesta. Actualizado para usar(void)presentViewController:(UIViewController *)viewControllerToPresent animated: (BOOL)flag completion:(void (^)(void))completion
Wayne

2
Cuando intento presentar un controlador de navegación, se bloquea ( 'NSInvalidArgumentException', reason: 'Pushing a navigation controller is not supported'). ¿Cómo puede funcionar esto?
pez remo

En mi caso, muestra una barra pero el otro contenido está colocado incorrectamente al presentar la animación. Y solo después de esta animación, salta a la posición correcta.
Vyachaslav Gerchicov

47

Swift 5.*

Navegación:

guard let myVC = self.storyboard?.instantiateViewController(withIdentifier: "MyViewController") else { return }
let navController = UINavigationController(rootViewController: myVC)

self.navigationController?.present(navController, animated: true, completion: nil)

Volver:

self.dismiss(animated: true, completion: nil)

Swift 2.0

Navegación:

let myVC = self.storyboard?.instantiateViewControllerWithIdentifier("MyViewController");
let navController = UINavigationController(rootViewController: myVC!)

self.navigationController?.presentViewController(navController, animated: true, completion: nil)

Volver:

self.dismissViewControllerAnimated(true, completion: nil)

1
Pero ¿Cómo establecer cuando intento su código único conjunto continuación, la barra de navegación, pero no puedo cambiar su propiedad como tinte color de la barra, título, etc.
Jaydip

No relacionado con esta pregunta, pero puede encontrar la respuesta aquí stackoverflow.com/questions/26008536/…
Tal Zion

23

Puedes usar:

[self.navigationController pushViewController:controller animated:YES];

Volviendo (creo):

[self.navigationController popToRootViewControllerAnimated:YES];

3
Gracias, la mejor manera de hacerlo si ya tiene un diseño de controlador de navegación en su guión gráfico. Me ayudaste mucho
phyzalis

volver es [self.navigationController popViewControllerAnimated: YES]; popToRoot - retrocediendo hasta el primer controlador de vista
Boris Gafurov

2

Tuve el mismo problema en ios7. Lo llamé en selector y funcionó tanto en ios7 como en ios8.

[self performSelector: @selector(showMainView) withObject: nil afterDelay: 0.0];

- (void) showMainView {
    HomeViewController * homeview = [
        [HomeViewController alloc] initWithNibName: @
        "HomeViewController"
        bundle: nil];
    UINavigationController * navcont = [
        [UINavigationController alloc] initWithRootViewController: homeview];
    navcont.navigationBar.tintColor = [UIColor whiteColor];
    navcont.navigationBar.barTintColor = App_Theme_Color;
    [navcont.navigationBar
    setTitleTextAttributes: @ {
        NSForegroundColorAttributeName: [UIColor whiteColor]
    }];
    navcont.modalPresentationStyle = UIModalPresentationFullScreen;
    navcont.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
    [self.navigationController presentViewController: navcont animated: YES completion: ^ {

    }];
}

1

Todo lo que [self.navigationController pushViewController:controller animated:YES];hace es animar una transición y agregarla a la pila del controlador de navegación, y algunas otras cosas interesantes de animación de la barra de navegación. Si no le importa la animación de la barra, entonces este código debería funcionar. La barra aparece en el nuevo controlador y obtienes un gesto pop interactivo.

//Make Controller
DetailViewController *controller = [[DetailViewController alloc] initWithNibName:nil                                                                                 
                                    bundle:[NSBundle mainBundle]];  
//Customize presentation
controller.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
controller.modalPresentationStyle = UIModalPresentationCurrentContext;

//Present controller
[self presentViewController:controller 
                   animated:YES 
                 completion:nil];
//Add to navigation Controller
[self navigationController].viewControllers = [[self navigationController].viewControllers arrayByAddingObject:controller];
//You can't just [[self navigationController].viewControllers addObject:controller] because viewControllers are for some reason not a mutable array.

Editar: Lo sentimos, presentViewController llenará la pantalla completa. Necesitará hacer una transición personalizada, con CGAffineTransform.translation o algo así, animar el controlador con la transición, luego agregarlo a los viewControllers de navigationController.


1

Swift 3

        let vc0 : ViewController1 = ViewController1()
        let vc2: NavigationController1 = NavigationController1(rootViewController: vc0)
        self.present(vc2, animated: true, completion: nil)

Cómo agregar el botón ATRÁS al UIViewController presentado
zulkarnain shah

1

Versión Swift: presenta un ViewController que está integrado en un controlador de navegación.

    override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    //  Identify the bundle by means of a class in that bundle.
    let storyboard = UIStoryboard(name: "Storyboard", bundle: NSBundle(forClass: SettingsViewController.self))

    // Instance of ViewController that is in the storyboard.
    let settingViewController = storyboard.instantiateViewControllerWithIdentifier("SettingsVC")

    let navController = UINavigationController(rootViewController: settingViewController)

    presentViewController(navController, animated: true, completion: nil)

}

1

Yo uso este código. Funciona bien en iOS 8.

MyProfileEditViewController *myprofileEdit=[self.storyboard instantiateViewControllerWithIdentifier:@"myprofileeditSid"];
UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:myprofileEdit];
[self presentViewController:navigationController animated:YES completion:^{}];

0

Una solución

DetailViewController *controller = [[DetailViewController alloc] initWithNibName:nil                                                                                 
                                        bundle:[NSBundle mainBundle]];  

UINavigationController *navController = [[UINavigationController alloc] initWithRootViewController:controller];
navController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
navController.modalPresentationStyle = UIModalPresentationCurrentContext;



[self.navigationController presentViewController:navController 
                                        animated:YES 
                                        completion:nil];

0

Si no configuró la propiedad modalPresentationStyle (como UIModalPresentationFormSheet), la barra de navegación se mostrará siempre. Para asegurarse, siempre haga

[[self.navigationController topViewController] presentViewController:vieController 
                                                            animated:YES 
                                                          completion:nil];

Esto mostrará la barra de navegación siempre.


Hmm ... incluso con la referencia fija a 'topViewController', sigo viendo el mismo comportamiento. No creo que esté agregando los otros controladores de vista a la pila de navegación de ninguna manera especial.
Jonas Gardner

0

Si usa NavigationController en Swift 2.x

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let targetViewController = storyboard.instantiateViewControllerWithIdentifier("targetViewControllerID") as? TargetViewController
self.navigationController?.pushViewController(targetViewController!, animated: true)

0

prueba esto

     let transition: CATransition = CATransition()
    let timeFunc : CAMediaTimingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    transition.duration = 1
    transition.timingFunction = timeFunc
    transition.type = kCATransitionPush
    transition.subtype = kCATransitionFromRight
    self.view.window!.layer.addAnimation(transition, forKey: kCATransition)
    self.presentViewController(vc, animated:true, completion:nil)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.