Como descartar o ViewController no Swift?

213

Estou tentando descartar um ViewController rapidamente, chamando dismissViewControllerumIBAction

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

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

imagem aleatória de um segue

Eu pude ver a mensagem println na saída do console, mas o ViewController nunca é descartado. Qual poderia ser o problema?

rshankar
fonte
2
Como você apresentou o controlador de exibição?
dasdom 10/07/2014
Fiz o mapeamento definindo um segue - "show", veja a captura de tela em anexo.
rshankar
4
Tente usar modal. Se você usar o push, deverá descartá-lo com o método pop do controlador de navegação.
dasdom 10/07/2014

Respostas:

414

Pela sua imagem, parece que você apresentou o ViewController usando push

O dismissViewControllerAnimatedé usado para fechar os ViewControllers apresentados usando modal

Swift 2

navigationController.popViewControllerAnimated(true)

Swift 4

navigationController?.popViewController(animated: true)

dismiss(animated: true, completion: nil)
Zoon Nooz
fonte
6
Como você faria isso para um 'Show Detail' segue?
MoralCode
2
Para Swift 2.2 navigationController .popViewControllerAnimated (true)!
swiftBoy
7
Para o Swift 3 navigationController! .PopViewController (animado: true) #
Alex Trott
174

Eu tenho uma solução para o seu problema. Por favor, tente este código para descartar o controlador de exibição se você apresentar a exibição usando modal:

Swift 3:

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

OU

Se você apresentar a visualização usando "push" segue

self.navigationController?.popViewController(animated: true)
satheesh
fonte
1
Obrigado, mas ainda o mesmo resultado, não descartar a ViewController
rshankar
4
Como isso difere do método usado pelo OP?
dasdom 10/07/2014
30
A conversa é inútil se você não reagir às minhas perguntas.
dasdom 10/07/2014
_ = self.navigationController? .popViewController (animado: true)
valexa
19

se você fizer isso, acho que você pode não receber a mensagem println no console,

@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
fonte
1
stackoverflow.com/questions/30840235/… . ? Qualquer ajuda, por favor, eu estou preso em que há tanto tempo que ainda solução achado não pode
Thiha Aung
14

No Swift 3.0 a 4.0, é tão fácil quanto digitar isso em sua função:

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

Ou, se você estiver em um controlador de navegação, poderá "pop-lo":

self.navigationController?.popViewController(animated: true)
Chase McElroy
fonte
descartar não funcionando, porque eu estou usando pushViewController. Apenas self.navigationController? .PopViewController (animated: true) funcionando.
iOS
13
  1. incorporar a exibição que você deseja descartar em um NavigationController
  2. adicione um BarButton com "Done" como identificador
  3. chamar o Editor Assistente com o botão Concluído selecionado
  4. crie uma IBAction para este botão
  5. adicione esta linha entre parênteses:

    self.dismissViewControllerAnimated(true, completion: nil)
ARTES LAOMUSICAS
fonte
12

Usar:

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

ao invés de:

self.navigationController.dismissViewControllerAnimated(true, completion: nil)
jobima
fonte
1
adicione um! ao navigationController e ele funciona para mim
Jason G
1
@naturalc: Esteja ciente de que, se o navigationController for nulo e você colocar!, o aplicativo
falhará
8

Se você apresentar um controlador sem um Controlador de Navegação, poderá chamar o código a seguir a partir de um método do controlador apresentado.

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

Se o seu ViewController for apresentado de forma modal, o opcional PresentationViewController não será nulo e o código será executado.

Peyotle
fonte
você salvou meu dia.
Shanu Singh 19/02
6

Com base na minha experiência, adiciono um método para me dispensar como extensão ao 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)
        }
    }
}

Então eu chamo esse método para descartar o view controller em qualquer UIViewControllersubclasse. Por exemplo, na ação cancelar:

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

Das documentações da Apple :

O controlador de exibição apresentado é responsável por descartar o controlador de exibição que ele apresentou

Portanto, é uma prática ruim invocar apenas o método de dispensa .

O que você deve fazer se estiver apresentando o modal é:

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

Não crie nenhuma sequência de Cancelar ou Concluído para outro VC e apenas escreva esse código nos seus botões @IBAction

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

Aqui está a única maneira de descartar o controlador de exibição atual e voltar ao controlador de exibição anterior. Você pode fazer isso apenas através do Storyboard.

  1. Open Storyboard
  2. Clique com o botão direito do mouse no botão Cancelar e arraste-o para o controlador de exibição anterior, onde deseja voltar ao controlador anterior
  3. Agora solte o botão direito e você poderá ver algumas ações que são executadas no botão Cancelar
  4. Agora escolha a opção "popover present" da lista
  5. Agora você pode descartar sua visualização atual clicando no botão Cancelar

Por favor, tente isso, está trabalhando comigo.

Segunda Via - Uso - navigationController.popViewControllerAnimated(true)

Boa sorte..

Chetan Bhalara
fonte
stackoverflow.com/questions/30840235/… . ? Qualquer ajuda, por favor, eu estou preso em que há tanto tempo que ainda solução achado não pode
Thiha Aung
3
Isto está errado. Você nunca está descartando a visualização. Em vez disso, está apresentando um novo controlador de visualização sobre o atual, causando um vazamento de memória. Provavelmente, seu aplicativo será rejeitado na loja de aplicativos.
3366784
2

Para referência, lembre-se de que você pode estar dispensando o controlador de exibição errado. Por exemplo, se você tem uma caixa de alerta ou modal sendo exibido em cima de outro modal. (Você pode exibir um alerta de postagem no Twitter sobre o alerta modal atual, por exemplo). Nesse caso, você precisa ligar para dispensar duas vezes ou usar um segue para descontrair.

mcfroob
fonte
1

Se você estiver apresentando um ViewController de forma modal e quiser voltar ao ViewController raiz, descarte esse ViewController apresentado antes de voltar ao ViewController raiz, caso contrário, esse ViewController não será removido da memória e causará vazamentos de memória.

dan
fonte
1

No Swift 3.0

Se você deseja descartar um controlador de exibição apresentado

self.dismiss(animated: true, completion: nil)
Ramakrishna
fonte
1

No Swift 4.1 e no Xcode 9.4.1

Se você usar o pushViewController para apresentar o novo controlador de exibição, use este

self.navigationController?.popViewController(animated: false)
iOS
fonte
Outra cópia colar resposta
J. Doe
1

Tente o seguinte:

@IBAction func close() {
  dismiss(animated: true, completion: nil)
}
cassiodiego
fonte
O método chamado "dispensViewController" requer apenas um único parâmetro, que suponho que gostaria de descartar animado para a visualização anterior, essa é a solução mais simples.
cassiodiego
0

Este código escrito na ação do botão para descartar

  @IBAction func cancel(sender: AnyObject) {
   dismiss(animated: true, completion: nil)
  }
Sai kumar Reddy
fonte
1
Embora esse trecho de código possa resolver a questão, incluir uma explicação realmente ajuda a melhorar a qualidade da sua postagem. Lembre-se de que você está respondendo à pergunta dos leitores no futuro e essas pessoas podem não saber os motivos da sua sugestão de código.
DimaSan
0
@IBAction func back(_ sender: Any) {
        self.dismiss(animated: false, completion: nil)
    }
eng mohamed emam
fonte
0

Se você estiver usando o método presente no VC pai, deverá chamar esta função, para descartar o VC filho, use este

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

se você chamar o VC filho usando o método push, para descartar o VC filho, use este

self.navigationController?.popViewController(animated: true)
Фаррух Махмудов
fonte