Navegue con rapidez mediante programación a otro controlador de vista / escena

81

Estoy usando el siguiente código para navegar programáticamente a otro ViewController. Funciona bien, pero de alguna manera oculta el navigation bar. ¿Cómo puedo solucionar esto? (la barra de navegación se crea insertando el ViewControlleren el navigation controllersi eso importa).

let storyBoard : UIStoryboard = UIStoryboard(name: "Main", bundle:nil)

let nextViewController = storyBoard.instantiateViewControllerWithIdentifier("nextView") as NextViewController
self.presentViewController(nextViewController, animated:true, completion:nil)
Víctor
fuente

Respuestas:

200

Rápido 5

El estilo de presentación modal predeterminado es una tarjeta. Esto muestra el controlador de vista anterior en la parte superior y permite al usuario deslizar el controlador de vista presentado.

Para conservar el estilo anterior, debe modificar el controlador de vista que presentará así:

newViewController.modalPresentationStyle = .fullScreen

Esto es lo mismo para los controladores creados mediante programación y creados con guiones gráficos.

Swift 3

Con un controlador creado mediante programación

Si desea navegar al controlador creado mediante programación, haga esto:

let newViewController = NewViewController()
self.navigationController?.pushViewController(newViewController, animated: true)

Con un controlador creado por StoryBoard

Si desea navegar a Controller en StoryBoard con el identificador "newViewController", haga esto:

let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "newViewController") as! NewViewController
        self.present(newViewController, animated: true, completion: nil)
jaiswal Rajan
fuente
2
"como! NewViewController" no es necesario en la opción de guión gráfico
Lavi Avigdor
2
sí, sé que es opcional, pero si lo mostramos, queda claro qué controlador de vista es el destino para otro desarrollador
jaiswal Rajan
4
Llame storyBoard.instantiateViewControllery self.presentdesde el hilo principal, o tendrá un retraso en la aparición de los componentes de viewController
Alex
2
@Alex mira, depende del desarrollador llamarlo desde el hilo principal, acabo de escribir la respuesta a la pregunta anterior. Su comentario para llamar desde el hilo principal no es apropiado aquí.
jaiswal Rajan
Hola gente: como regla general, ¿puedo sugerir un tono más amigable? (Esto es un problema aquí en SO) Para el tema, en su lugar: a pesar de que no ha pedido directamente por OP, creo que esta buena respuesta sigue siendo un lugar apropiado para recordar (a la lectura a nadie) que la acción tiene que ocurrir en el hilo principal
superjos 3/04/19
32

SWIFT 4.x

Las cadenas entre comillas dobles siempre me confunden, así que creo que la respuesta a esta pregunta necesita una presentación gráfica para aclarar esto.

Para una aplicación bancaria, tengo un LoginViewController y un BalanceViewController. Cada uno tiene sus respectivas pantallas.

La aplicación se inicia y muestra la pantalla de inicio de sesión. Cuando el inicio de sesión es exitoso, la aplicación abre la pantalla Balance.

Así es como se ve:

ingrese la descripción de la imagen aquí

ingrese la descripción de la imagen aquí

El éxito del inicio de sesión se maneja así:

let storyBoard: UIStoryboard = UIStoryboard(name: "Balance", bundle: nil)
let balanceViewController = storyBoard.instantiateViewController(withIdentifier: "balance") as! BalanceViewController
self.present(balanceViewController, animated: true, completion: nil)

Como puede ver, el 'balance' de ID del guión gráfico en letras pequeñas es lo que va en la segunda línea del código, y este es el ID que se define en la configuración del guión gráfico, como en la captura de pantalla adjunta.

El término 'Balance' con mayúscula 'B' es el nombre del archivo del guión gráfico , que se utiliza en la primera línea del código.

Sabemos que usar cadenas codificadas de forma rígida en el código es una muy mala práctica, pero de alguna manera en el desarrollo de iOS se ha convertido en una práctica común, y Xcode ni siquiera advierte sobre ellos.

Zeeshan
fuente
impresionantes demostraciones
Elias Fazel
1
¡Amigo, eres increíble!
OhhhThatVarun
15

Debe impulsar el nuevo controlador de vista utilizando el controlador de navegación actual, no presente.

self.navigationController.pushViewController(nextViewController, animated: true)
Okan Kocyigit
fuente
¿Por qué deberíamos presionar si hay algún beneficio?
DragonFire
1
@DragonFire, porque op quiere que funcione sin cubrir la barra de navegación. Si desea tener un diseño de página principal con detalles, como entre la pantalla de contactos de WhatsApp y la pantalla de chat, debe pushusar el controlador de vista con su controlador de navegación. (que se animará de izquierda a derecha) si solo desea mostrar, presentar, una ventana emergente en la pantalla actual (que se animará de abajo hacia arriba), solo use present.
Okan Kocyigit
12

Según @jaiswal Rajan en su respuesta . Puedes hacer un pushViewController como este:

let storyBoard: UIStoryboard = UIStoryboard(name: "NewBotStoryboard", bundle: nil)
let newViewController = storyBoard.instantiateViewController(withIdentifier: "NewViewController") as! NewViewController
self.navigationController?.pushViewController(newViewController, animated: true)
Andres Paladines
fuente
1
Hola, solo me preguntaba: ¿por qué repetir la respuesta ya publicada? Quizás un comentario o un voto positivo también hubiera estado bien. ¿O hay más razonamientos detrás?
superjos
Se presenta para navegar con NavigationController. Gracias.
Hiran DA Walawage
4

Entonces, si presenta un controlador de vista, no se mostrará en el controlador de navegación. Solo tomará la pantalla completa. Para este caso, debe crear otro controlador de navegación y agregar su nextViewControllercomo root para esto y presentar este nuevo controlador de navegación.

Otra forma es simplemente presionar el controlador de vista.

self.presentViewController(nextViewController, animated:true, completion:nil)

Para obtener más información, consulte la documentación de Apple: - https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIViewController_Class/#//apple_ref/doc/uid/TP40006926-CH3-SW96

Aks
fuente
presentViewControllerha cambiado de nombre a present(loginController, animated:true, completion:nil)
kite_n_code
2
OperationQueue.main.addOperation {
   let storyBoard: UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
   let newViewController = storyBoard.instantiateViewController(withIdentifier: "Storyboard ID") as! NewViewController
   self.present(newViewController, animated: true, completion: nil)
}

Me funcionó cuando puse el código dentro del OperationQueue.main.addOperation, que se ejecutará en el hilo principal por mí.

Pedro Berbel
fuente
1

El código anterior funciona bien, pero si desea navegar desde una NSObjectclase, donde no puede usar self.present:

let storyBoard = UIStoryboard(name:"Main", bundle: nil)
if let conVC = storyBoard.instantiateViewController(withIdentifier: "SoundViewController") as? SoundViewController,
    let navController = UIApplication.shared.keyWindow?.rootViewController as? UINavigationController {
    
    navController.pushViewController(conVC, animated: true)
}
Bhargav
fuente
0

Todas las demás respuestas suenan bien, me gustaría cubrir mi caso, donde tuve que hacer una LaunchScreen animada, luego, después de 3 a 4 segundos de animación, la siguiente tarea fue pasar a la pantalla de inicio. Intenté segues, pero eso creó un problema para la vista de destino. Así que al final accedí a la propiedad Window de AppDelegates y le asigné una nueva pantalla NavigationController,

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let homeVC = storyboard.instantiateViewController(withIdentifier: "HomePageViewController") as! HomePageViewController

//Below's navigationController is useful if u want NavigationController in the destination View
let navigationController = UINavigationController(rootViewController: homeVC)
appDelegate.window!.rootViewController = navigationController

En caso de que no desee navigationController en la vista de destino, simplemente asigne como,

let storyboard = UIStoryboard(name: "Main", bundle: nil)
let appDelegate = UIApplication.shared.delegate as! AppDelegate
let homeVC = storyboard.instantiateViewController(withIdentifier: "HomePageViewController") as! HomePageViewController
appDelegate.window!.rootViewController = homeVC
shubham mishra
fuente