Как уволить ViewController в Swift?

164

Я пытаюсь отклонить ViewController в swift, вызывая dismissViewController в IBAction

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

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

Изображение 67

Я мог видеть сообщение println на выходе консоли, но ViewController никогда не увольняется. В чем может быть проблема?

  • 2
    Как вы представили контроллер вида?
  • 0
    Я сделал отображение, установив segue - «шоу», см. Прикрепленный скриншот.
Показать ещё 1 комментарий
Теги:
viewcontroller

16 ответов

325
Лучший ответ

Из вашего изображения кажется, что вы представили ViewController, используя push

dismissViewControllerAnimated используется для закрытия ViewControllers, представленных с использованием модальных

Swift 2

navigationController.popViewControllerAnimated(true)

Swift 4

navigationController?.popViewController(animated: true)

dismiss(animated: true, completion: nil)
  • 6
    Как бы вы сделали это для передачи 'Show Detail'?
  • 2
    Для Swift 2.2 navigationController! .PopViewControllerAnimated (true)
Показать ещё 2 комментария
162

У меня есть решение проблемы. Попробуйте этот код, чтобы закрыть диспетчер представлений, если вы представляете представление с помощью модального:

Swift 3:

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

ИЛИ

Если вы представляете представление, используя "push" segue

self.navigationController?.popViewController(animated: true)
  • 1
    Спасибо, но результат все тот же, он не увольняет ViewController
  • 4
    Как это отличается от метода, используемого ОП?
Показать ещё 2 комментария
17

если вы это сделаете, я думаю, вы не можете получить сообщение println в консоли,

@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/… . Любая помощь, пожалуйста? Я застрял в этом так долго, кто до сих пор не может найти решение
13
  • встроить View, который вы хотите удалить в NavigationController
  • добавить BarButton с "Done" в качестве идентификатора
  • вызвать редактор-помощник с выбранной кнопкой "Готово"
  • создайте IBAction для этой кнопки
  • добавьте эту строку в скобки:

    self.dismissViewControllerAnimated(true, completion: nil)
    
10

В Swift 3.0 до 4.0 это так же просто, как ввести это в вашу функцию:

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

Или, если вы находитесь в контроллере навигации, вы можете "поп" его:

self.navigationController?.popViewController(animated: true)
  • 0
    уволить не работает, потому что я использую pushViewController. Работает только self.navigationController? .PopViewController (animated: true).
10

Использование:

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

вместо:

self.navigationController.dismissViewControllerAnimated(true, completion: nil)
  • 1
    добавить ! к навигационному контроллеру и он у меня работает
  • 1
    @naturalc: Имейте в виду, что если навигационный контроллер равен нулю, и вы положили!, приложение потерпит крах
7

Если вы представляете контроллер без контроллера навигации, вы можете вызвать следующий код из метода представленного контроллера.

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

Если ваш ViewController представлен модально, необязательный presentingViewController не будет равен нулю, и код будет выполнен.

5

Основываясь на моем опыте, я добавляю метод отклонения меня как расширения для 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)
        }
    }
}

Затем я вызываю этот метод, чтобы отклонить контроллер представления в любом подклассе UIViewController. Например, в случае отмены действия:

class MyViewController: UIViewController {
   ...
   @IBAction func cancel(sender: AnyObject) {
     dismissMe(animated: true, completion: nil)
   }
   ...
}
  • 0
    работает хорошо для меня!
4

Не создавайте никаких отступ от Отмена или Готово к другому VC и только пишите этот код кнопками @IBAction

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

Вот один из способов отклонить текущий контроллер представления и вернуться к предыдущему контроллеру представления. Вы можете сделать это только с помощью раскадровки.

  • Открытая раскадровка
  • Щелкните правой кнопкой мыши на кнопке Отмена и перетащите ее на предыдущий контроллер представления, где вы хотите вернуться к предыдущему контроллеру.
  • Теперь отпустите правый клик, и вы увидите некоторые действия, которые выполняются при нажатии кнопки
  • Теперь выберите "popover present" из списка
  • Теперь вы можете отклонить текущий вид, нажав кнопку отмены

Пожалуйста, попробуйте это, он работает со мной.

Второй способ - Использовать - navigationController.popViewControllerAnimated(true)

Удачи..

  • 0
    stackoverflow.com/questions/30840235/… . Любая помощь, пожалуйста? Я застрял в этом так долго, кто до сих пор не может найти решение
  • 2
    Это не верно. Вы никогда не отклоняете представление, вместо этого вы представляете новый контроллер представления поверх текущего, что приводит к утечке памяти. Это, скорее всего, приведет к отклонению вашего приложения в магазине приложений.
2

Для справки, имейте в виду, что вы можете отклонить неправильный контроллер. Например, если у вас есть окно предупреждения или модальное отображение поверх другого модального. (Например, у вас может быть предупреждение о появлении на Twitter, например, поверх вашего текущего модального предупреждения). В этом случае вам нужно дважды вызвать увольнение или использовать разматывание.

1

Из документации Apple:

Контроллер представления представления отвечает за отклонение контроллера представления, который он представил

Таким образом, это плохая практика просто вызывать метод увольнения из него.

Что вы должны делать, если вы представляете его модальным:

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

В Swift 4.1 и Xcode 9.4.1

Если вы используете pushViewController для представления нового контроллера представлений, используйте это

self.navigationController?.popViewController(animated: false)
  • 0
    Еще одна копия вставьте ответ
1

Если вы представляете ViewController модально и хотите вернуться к корневому ViewController, позаботьтесь об отказе от этого модально представленного ViewController, прежде чем вернуться к корневому ViewController, иначе этот ViewController не будет удален из памяти и вызовет утечку памяти.

0

В Swift 3.0

Если вы хотите отклонить представленный контроллер представления

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

Этот код, написанный в действии кнопки для отклонения

  @IBAction func cancel(sender: AnyObject) {
   dismiss(animated: true, completion: nil)
  }
  • 1
    Хотя этот фрагмент кода может решить вопрос, в том числе объяснение действительно помогает улучшить качество вашего сообщения. Помните, что вы отвечаете на вопрос читателей в будущем, и эти люди могут не знать причин, по которым вы предлагаете код.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню