Jak zamknąć ViewController w Swift?


214

Usiłuję szybko zwolnić ViewController, wywołując dismissViewControllernumerIBAction

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

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

losowy obraz segue

Widziałem komunikat println w danych wyjściowych konsoli, ale ViewController nigdy nie zostaje odrzucony. Co może być problemem?


2
Jak przedstawiłeś kontroler widoku?
dasdom

Zrobiłem mapowanie, ustawiając segue - „pokaż”, patrz załączony zrzut ekranu.
rshankar

4
Spróbuj użyć modalu. Jeśli używasz push, powinieneś go odrzucić za pomocą metody pop kontrolera nawigacji.
dasdom

Odpowiedzi:


415

Z twojego obrazu wydaje się, że przedstawiłeś ViewController za pomocą push

The dismissViewControllerAnimatedSłuży do bliskich ViewControllers że prezentowane za pomocą modal

Swift 2

navigationController.popViewControllerAnimated(true)

Szybki 4

navigationController?.popViewController(animated: true)

dismiss(animated: true, completion: nil)

6
Jak byś to zrobił dla segmentu „Pokaż szczegóły”?
MoralCode

2
Dla Swift 2.2 navigationController! .PopViewControllerAnimated (true)
swiftBoy

7
Dla nawigacji Swift 3Controller! .PopViewController (animowane: true)
Alex Trott

174

Mam rozwiązanie twojego problemu. Wypróbuj ten kod, aby zamknąć kontroler widoku, jeśli prezentujesz widok za pomocą modalu:

Swift 3:

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

LUB

Jeśli przedstawisz widok za pomocą „push” segue

self.navigationController?.popViewController(animated: true)

1
Dzięki, ale wciąż ten sam wynik, nie zwalnia ViewController
rshankar

4
Czym różni się to od metody zastosowanej przez PO?
dasdom

30
Rozmowa jest bezużyteczna, jeśli nie zareagujesz na moje pytania.
dasdom

_ = self.navigationController? .popViewController (animowane: true)
valexa

19

jeśli to zrobisz, prawdopodobnie nie otrzymasz wiadomości println w konsoli,

@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")
  }    
}


14

W Swift 3.0 do 4.0 jest to tak proste, jak wpisanie tego w swojej funkcji:

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

Lub jeśli jesteś w kontrolerze nawigacyjnym, możesz go „pop”:

self.navigationController?.popViewController(animated: true)

odrzuć nie działa, ponieważ używam pushViewController. Działa tylko self.navigationController? .PopViewController (animowany: prawda).
iOS

13
  1. osadzić widok, który chcesz zamknąć, w Nawigatorze nawigacji
  2. dodaj przycisk BarButton z „Gotowe” jako identyfikator
  3. wywołać Asystenta edytora z wybranym przyciskiem Gotowe
  4. utwórz IBAction dla tego przycisku
  5. dodaj tę linię w nawiasach:

    self.dismissViewControllerAnimated(true, completion: nil)

12

Posługiwać się:

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

zamiast:

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

1
dodać ! do NavigationController i działa dla mnie
Jason G

1
@naturalc: Należy pamiętać, że jeśli NavigationController ma wartość zero i umieścisz!, aplikacja ulegnie awarii
jobima

8

Jeśli prezentujesz kontroler bez kontrolera nawigacyjnego, możesz wywołać następujący kod z metody prezentowanej kontrolera.

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

Jeśli Twój ViewController jest prezentowany modalnie, opcjonalny prezentujący ViewController nie będzie zerowy i kod zostanie wykonany.


uratowałeś mi dzień
Shanu Singh

6

W oparciu o moje doświadczenie dodaję metodę, aby odrzucić mnie jako rozszerzenie 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)
        }
    }
}

Następnie wywołuję tę metodę, aby zamknąć kontroler widoku w dowolnej UIViewControllerpodklasie. Na przykład w akcji anulowania:

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

6

Z dokumentacji Apple :

Prezentujący kontroler widoku jest odpowiedzialny za odwołanie kontrolera widoku, który przedstawił

Dlatego złym zwyczajem jest po prostu przywołanie metody „ odrzuć” od siebie.

Co należy zrobić, jeśli prezentujesz to modalnie, to:

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

4

Nie twórz żadnego segmentu od Anuluj lub Gotowe do innego VC i pisz ten kod tylko przyciskami @IBAction

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

3

Oto jeden ze sposobów zamknięcia obecnego kontrolera widoku i powrotu do poprzedniego kontrolera widoku. Możesz to zrobić tylko poprzez Storyboard.

  1. Otwórz Storyboard
  2. Kliknij prawym przyciskiem myszy przycisk Anuluj i przeciągnij go do poprzedniego kontrolera widoku, gdzie chcesz wrócić do poprzedniego kontrolera
  3. Teraz zwolnij prawy przycisk myszy, a zobaczysz akcje wykonywane po naciśnięciu przycisku Anuluj
  4. Teraz wybierz z listy opcję „popover present”
  5. Teraz możesz odrzucić swój obecny widok, klikając przycisk Anuluj

Spróbuj tego, działa ze mną.

Drugi sposób - użycie - navigationController.popViewControllerAnimated(true)

Powodzenia



3
To jest źle. Nigdy nie odrzucasz widoku, zamiast tego prezentujesz nowy kontroler widoku na bieżącym, powodując przeciek pamięci. Najprawdopodobniej Twoja aplikacja zostanie odrzucona ze sklepu z aplikacjami.
3366784

2

W celach informacyjnych pamiętaj, że możesz odrzucić niewłaściwy kontroler widoku. Na przykład, jeśli na innym modale wyświetla się pole ostrzeżenia lub modal. (Możesz na przykład wyświetlać powiadomienie na Twitterze nad aktualnym powiadomieniem modalnym). W takim przypadku musisz dwukrotnie wywołać odwołanie lub skorzystać z odwijanego segmentu.


1

Jeśli prezentujesz ViewController w sposób modalny i chcesz wrócić do głównego ViewController, pamiętaj, aby odrzucić ten modalnie prezentowany ViewController przed powrotem do głównego ViewController, w przeciwnym razie ten ViewController nie zostanie usunięty z pamięci i spowoduje wyciek pamięci.


1

W Swift 3.0

Jeśli chcesz zamknąć przedstawiony kontroler widoku

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

1

W Swift 4.1 i Xcode 9.4.1

Jeśli używasz pushViewController do prezentacji nowego kontrolera widoku, użyj tego

self.navigationController?.popViewController(animated: false)

Kolejna odpowiedź na kopię wklej
J. Doe

1

Spróbuj tego:

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

Metoda o nazwie „dismissViewController” wymaga tylko jednego parametru, który, jak sądzę, chciałby odrzucić animowany do poprzedniego widoku, jest to najprostsze rozwiązanie.
cassiodiego

0

Ten kod napisany w akcji przycisku do odrzucenia

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

1
Ten fragment kodu może rozwiązać pytanie, ale wyjaśnienie naprawdę pomaga poprawić jakość posta. Pamiętaj, że w przyszłości odpowiadasz na pytanie dla czytelników, a ci ludzie mogą nie znać przyczyn Twojej sugestii kodu.
DimaSan,


0

Jeśli używasz obecnej metody w nadrzędnym VC, powinieneś wywołać tę funkcję, aby zamknąć potomne VC użyj tego

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

jeśli wywołujesz dziecko VC za pomocą metody wypychania, aby je odrzucić, użyj tego

self.navigationController?.popViewController(animated: true)
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.