¿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?

rshankar
fuente
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)
Zoon Nooz
fuente
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)
satheesh
fuente
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")
  }    
}
BaSha
fuente
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)
Chase McElroy
fuente
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)
ARTES LAOMUSICAS
fuente
12

Utilizar:

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

en vez de:

self.navigationController.dismissViewControllerAnimated(true, completion: nil)
Jobima
fuente
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.

Peyotle
fuente
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)
   }
   ...
}
David.Chu.ca
fuente
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)
OhadM
fuente
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)
}
Fatih
fuente
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..

Chetan Bhalara
fuente
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.

Mcfroob
fuente
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.

dan
fuente
1

En Swift 3.0

Si desea descartar un controlador de vista presentado

self.dismiss(animated: true, completion: nil)
Ramakrishna
fuente
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)
iOS
fuente
Otra respuesta de copiar y pegar
J. Doe
1

Prueba esto:

@IBAction func close() {
  dismiss(animated: true, completion: nil)
}
Cassiodiego
fuente
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)
  }
Sai kumar Reddy
fuente
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
@IBAction func back(_ sender: Any) {
        self.dismiss(animated: false, completion: nil)
    }
eng mohamed emam
fuente
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)
Фаррух Махмудов
fuente