¿Cómo descartar ViewController en Swift?


213

Estoy tratando de descartar un ViewController rápidamente llamando dismissViewControllera unIBAction

  @IBAction func cancel(sender: AnyObject) {
    self.dismissViewControllerAnimated(false, completion: nil)
    println("cancel")
}

@IBAction func done(sender: AnyObject) {
    self.dismissViewControllerAnimated(false, completion: nil)
    println("done")
}

imagen aleatoria de un segue

Pude ver el mensaje println en la salida de la consola, pero ViewController nunca se descarta. ¿Cual podría ser el problema?


2
¿Cómo presentó el controlador de vista?
dasdom

Hice el mapeo configurando un segue - "show", mira la captura de pantalla adjunta.
rshankar

44
Intenta usar modal. Si usa push, debe descartarlo con el método pop del controlador de navegación.
dasdom

Respuestas:


414

De su imagen parece que presentó el ViewController usando push

Se dismissViewControllerAnimatedusa para cerrar ViewControllers que se presentaron usando modal

Swift 2

navigationController.popViewControllerAnimated(true)

Swift 4

navigationController?.popViewController(animated: true)

dismiss(animated: true, completion: nil)

66
¿Cómo lo harías para una sesión 'Mostrar detalles'?
MoralCode

2
Para Swift 2.2 navigationController! .PopViewControllerAnimated (verdadero)
swiftBoy

77
Para Swift 3 navigationController! .PopViewController (animado: verdadero)
Alex Trott

174

Tengo una solución para tu problema. Pruebe este código para descartar el controlador de vista si presenta la vista usando modal:

Swift 3:

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

O

Si presenta la vista utilizando "push" segue

self.navigationController?.popViewController(animated: true)

1
Gracias, pero sigue siendo el mismo resultado, no descarta el ViewController
rshankar

44
¿Cómo es esto diferente al método que utilizó el OP?
dasdom

30
La conversación es inútil si no reaccionas a mis preguntas.
dasdom

_ = self.navigationController? .popViewController (animado: verdadero)
valexa

19

si haces esto, supongo que es posible que no recibas el mensaje println en la consola,

@IBAction func cancel(sender: AnyObject) {
  if(self.presentingViewController){
    self.dismissViewControllerAnimated(false, completion: nil)
    println("cancel")
   }
}

@IBAction func done(sender: AnyObject) {
  if(self.presentingViewController){
    self.dismissViewControllerAnimated(false, completion: nil)
    println("done")
  }    
}

1
stackoverflow.com/questions/30840235/… . ¿Alguna ayuda, por favor? Estoy atrapado en eso por tanto tiempo que todavía no puedo encontrar la solución
Thiha Aung

14

En Swift 3.0 a 4.0 es tan fácil como escribir esto en su función:

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

O si está en un controlador de navegación puede "abrirlo":

self.navigationController?.popViewController(animated: true)

descartar no funciona, porque estoy usando pushViewController. Solo self.navigationController? .PopViewController (animado: verdadero) funciona.
iOS

13
  1. incrustar la vista que desea descartar en un NavigationController
  2. agregar un BarButton con "Listo" como Identificador
  3. invoque el Editor Asistente con el botón Listo seleccionado
  4. crear una IBAction para este botón
  5. agregue esta línea entre paréntesis:

    self.dismissViewControllerAnimated(true, completion: nil)

12

Utilizar:

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

en vez de:

self.navigationController.dismissViewControllerAnimated(true, completion: nil)

1
Agrega un ! a la NavigationController y funciona para mí
Jason G

1
@naturalc: Tenga en cuenta que si navigationController es nulo y lo pone, la aplicación se bloqueará
jobima

8

Si presenta un controlador sin un controlador de navegación, puede llamar al siguiente código desde un método del controlador presentado.

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

Si su ViewController se presenta modalmente, la presentación opcional ViewController no será nula y se ejecutará el código.


Salvaste mi día.
Shanu Singh

6

Según mi experiencia, agrego un método para descartarme como extensión de UIViewController:

extension UIViewController {
    func dismissMe(animated: Bool, completion: (()->())?) {
        var count = 0
        if let c = self.navigationController?.viewControllers.count {
            count = c
        }
        if count > 1 {
            self.navigationController?.popViewController(animated: animated)
            if let handler = completion {
                handler()
            }
        } else {
            dismiss(animated: animated, completion: completion)
        }
    }
}

Luego llamo a este método para descartar el controlador de vista en cualquier UIViewControllersubclase. Por ejemplo, en la acción cancelar:

class MyViewController: UIViewController {
   ...
   @IBAction func cancel(sender: AnyObject) {
     dismissMe(animated: true, completion: nil)
   }
   ...
}

6

De las documentaciones de Apple :

El controlador de vista de presentación es responsable de descartar el controlador de vista que presentó

Por lo tanto, es una mala práctica invocar el método de descarte de sí mismo.

Lo que debe hacer si lo presenta modal es:

presentingViewController?.dismiss(animated: true, completion: nil)

4

No cree ningún paso desde Cancelar o Listo a otro VC y solo escriba este código en sus botones @IBAction

@IBAction func cancel(sender: AnyObject) {
    dismiss(animated: false, completion: nil)
}

3

Esta es la única forma de descartar el controlador de vista actual y volver al controlador de vista anterior. Puede hacer esto solo a través de Storyboard.

  1. Abrir Storyboard
  2. Haga clic derecho en el botón Cancelar y arrástrelo al controlador de vista anterior, donde desea volver al controlador anterior
  3. Ahora suelte el clic derecho y podrá ver algunas acciones que se realizan en el botón Cancelar
  4. Ahora elija la opción "popover present" de la lista
  5. Ahora puede cerrar su vista actual haciendo clic en el botón Cancelar

Por favor intente esto, está trabajando conmigo.

Segunda forma - Uso - navigationController.popViewControllerAnimated(true)

La mejor de las suertes..


stackoverflow.com/questions/30840235/… . ¿Alguna ayuda, por favor? Estoy atrapado en eso por tanto tiempo que todavía no puedo encontrar la solución
Thiha Aung

3
Esto está mal. Nunca descarta la vista, sino que presenta un nuevo controlador de vista encima del actual, lo que provoca una pérdida de memoria. Esto probablemente hará que su aplicación sea rechazada de la tienda de aplicaciones.
3366784

2

Como referencia, tenga en cuenta que puede estar descartando el controlador de vista incorrecto. Por ejemplo, si tiene un cuadro de alerta o modal que se muestra encima de otro modal. (Podría tener una alerta de publicación de Twitter que se muestre encima de su alerta modal actual, por ejemplo). En este caso, debe llamar a descartar dos veces, o usar un segue de desenrollado.


1

Si presenta un ViewController modalmente y desea volver al ViewController raíz, tenga cuidado de descartar este ViewController presentado de manera modal antes de volver al ViewController raíz; de lo contrario, este ViewController no se eliminará de la memoria y provocará pérdidas de memoria.


1

En Swift 3.0

Si desea descartar un controlador de vista presentado

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

1

En Swift 4.1 y Xcode 9.4.1

Si usa pushViewController para presentar un nuevo controlador de vista, use esto

self.navigationController?.popViewController(animated: false)

Otra respuesta de copiar y pegar
J. Doe

1

Prueba esto:

@IBAction func close() {
  dismiss(animated: true, completion: nil)
}

El método llamado "DespideViewController" solo toma un único parámetro, que supongo que parecería descartar animado a la vista anterior, esta es la solución más simple.
cassiodiego 05 de

0

Este código escrito en la acción del botón para descartar

  @IBAction func cancel(sender: AnyObject) {
   dismiss(animated: true, completion: nil)
  }

1
Si bien este fragmento de código puede resolver la pregunta, incluir una explicación realmente ayuda a mejorar la calidad de su publicación. Recuerde que está respondiendo la pregunta para los lectores en el futuro, y que esas personas podrían no conocer los motivos de su sugerencia de código.
DimaSan


0

Si usa el método presente en el VC primario, entonces debe llamar a esta función, para descartar el VC secundario, use esto

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

si llama al VC secundario mediante el método push, para descartar el VC secundario, utilice este

self.navigationController?.popViewController(animated: true)
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.