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?

rshankar
źródło
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)
Zoon Nooz
źródło
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)
satheesh
źródło
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")
  }    
}
BaSha
źródło
1
stackoverflow.com/questions/30840235/… . Jakaś pomoc, proszę?
Utknąłem
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)
Chase McElroy
źródło
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)
SZTUKI LAOMUZYCZNE
źródło
12

Posługiwać się:

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

zamiast:

self.navigationController.dismissViewControllerAnimated(true, completion: nil)
Jobima
źródło
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.

Peyotle
źródło
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)
   }
   ...
}
David.Chu.ca
źródło
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)
OhadM
źródło
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)
}
Fatih
źródło
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

Chetan Bhalara
źródło
stackoverflow.com/questions/30840235/… . Jakaś pomoc, proszę?
Utknąłem
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.

McFroob
źródło
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.

dan
źródło
1

W Swift 3.0

Jeśli chcesz zamknąć przedstawiony kontroler widoku

self.dismiss(animated: true, completion: nil)
Ramakrishna
źródło
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)
iOS
źródło
Kolejna odpowiedź na kopię wklej
J. Doe
1

Spróbuj tego:

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