Як відмовити ViewController у Swift?


214

Я намагаюся швидко відхилити ViewController, зателефонувавши 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")
}

випадкове зображення сеги

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


2
Як ви представили контролер перегляду?
dasdom

Я зробив картування, встановивши segue - "показати", дивіться доданий скріншот.
rshankar

4
Спробуйте використовувати модальний. Якщо ви використовуєте push, слід відхилити його за допомогою поп-методу навігаційного контролера.
dasdom

Відповіді:


415

З вашого зображення, схоже, ви представили ViewController за допомогою push

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

Швидкий 2

navigationController.popViewControllerAnimated(true)

Швидкий 4

navigationController?.popViewController(animated: true)

dismiss(animated: true, completion: nil)

6
Як би ви це зробили для фільму "Показати деталь"?
MoralCode

2
Для навігації Swift 2.2 ! Контролер! .PopViewControllerAnimated (true)
swiftBoy

7
Для навігаційної програми Swift 3 ! .PopViewController (анімовані: правда)
Алекс Тротт

174

У мене є рішення для вашої проблеми. Спробуйте скористатися цим кодом, щоб відхилити контролер перегляду, якщо ви подаєте подання за допомогою модального режиму:

Швидкий 3:

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

АБО

Якщо ви представите вид за допомогою "push" segue

self.navigationController?.popViewController(animated: true)

1
Дякую, але все-таки той самий результат, він не відхиляє ViewController
rshankar

4
Чим це відрізняється від методу використання ОП?
dasdom

30
Розмова марна, якщо ви не реагуєте на мої запитання.
dasdom

_ = self.navigationController? .popViewController (анімовані: правда)
valexa

19

якщо ви це зробите, я думаю, ви не можете отримати повідомлення 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/… . Будь-яка допомога, будь ласка? Я затримався на цьому так довго, хто все ще не може знайти рішення
Thiha Aung

14

У Swift 3.0 до 4.0 це так просто, як ввести це у свою функцію:

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

Або якщо ви перебуваєте в навігаційному контролері, ви можете "пропустити" його

self.navigationController?.popViewController(animated: true)

відхилити не працює, тому що я використовую pushViewController. Працює лише self.navigationController? .PopViewController (анімований: правда).
iOS

13
  1. вбудувати вигляд, який ви хочете відхилити, у NavigationController
  2. додайте BarButton з "Готово" як ідентифікатор
  3. викликати помічник редактора, вибравши кнопку Готово
  4. створити IBAction для цієї кнопки
  5. додайте цей рядок у дужки:

    self.dismissViewControllerAnimated(true, completion: nil)

12

Використання:

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

замість:

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

1
додати! до навігаційного контролера, і він працює для мене
Jason G

1
@naturalc: Будьте в курсі, що якщо navigationController буде нульовим, і ви покладете !, додаток вийде з
ладу

8

Якщо ви представляєте контролер без контролера навігації, ви можете викликати наступний код із способу представленого контролера.

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

Якщо ваш ViewController представлений модально, необов'язково представленняViewController не буде нульовим, і код буде виконаний.


ти врятував мій день.
Шану Сінгх

6

На основі свого досвіду я додаю метод звільнення мене як розширення до 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)
   }
   ...
}

6

З документації Apple :

Контролер подання подання відповідає за відхилення представленого ним контролера

Таким чином, є поганою практикою просто посилатися на метод звільнення з нього самостійно.

Що ви повинні зробити, якщо ви представляєте його модально:

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

4

Не створюйте жодних слів із Скасувати або Готово до інших ВК, а лише записуйте цей код своїми кнопками @IBAction

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

3

Ось один із способів відхилити поточний контролер подання та повернутися до попереднього контролера подання. Це можна зробити лише через аркуш розгортки.

  1. Відкрити дошку розгортки
  2. Клацніть правою кнопкою миші кнопку Скасувати та перетягніть її на попередній контролер перегляду, де ви хочете повернутися до попереднього контролера
  3. Тепер відпустіть правий клік і ви зможете побачити деякі дії, які виконуються на кнопку скасувати
  4. Тепер виберіть у списку опцію "переповнений час"
  5. Тепер ви можете відмовитись від поточного перегляду, натиснувши кнопку скасувати

Спробуйте, це працює зі мною.

Другий спосіб - використання - navigationController.popViewControllerAnimated(true)

Найкраща удача ..


stackoverflow.com/questions/30840235/… . Будь-яка допомога, будь ласка? Я затримався на цьому так довго, хто все ще не може знайти рішення
Thiha Aung

3
Це неправильно. Ви ніколи не відхиляєте подання, а натомість представляєте новий контролер перегляду поверх поточного, що спричиняє витік пам'яті. Швидше за все, ваш додаток буде відхилено з магазину додатків.
3366784

2

Для довідки майте на увазі, що ви можете відхилити неправильний контролер подання. Наприклад, якщо у вас є поле сповіщення або модальний режим, який відображається поверх іншого модалу. (Можливо, у вас може з’явитися повідомлення про Twitter, яке відображається, наприклад, над поточним модальним попередженням). У цьому випадку вам потрібно зателефонувати звільнити двічі або скористатися розмоткою.


1

Якщо ви представляєте ViewController модально і хочете повернутися до кореневого ViewController, будьте обережні, щоб відмовитись від цього модально представленого ViewController перед тим, як повернутися до кореня ViewController, інакше цей ViewController не буде вилучений з пам'яті і не спричинить витоку пам'яті.


1

У Swift 3.0

Якщо ви хочете відхилити представлений контролер перегляду

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

1

У Swift 4.1 та Xcode 9.4.1

Якщо ви використовуєте pushViewController для представлення нового контролера перегляду, використовуйте це

self.navigationController?.popViewController(animated: false)

Ще одна відповідь на примірник вставки
Дж. Дой

1

Спробуйте це:

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

У методі під назвою "dismissViewController" він приймає лише один параметр, який, мабуть, виглядав би як відхилення анімованих до попереднього перегляду, це найпростіше рішення.
cassiodiego

0

Цей код написаний у дії кнопки для відхилення

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

1
Хоча цей фрагмент коду може вирішити питання, у тому числі пояснення дійсно допомагає покращити якість вашої публікації. Пам'ятайте, що ви відповідаєте на запитання читачів у майбутньому, і ці люди можуть не знати причини вашої пропозиції щодо коду.
DimaSan


0

Якщо ви використовуєте даний метод у батьківському VC, вам слід викликати цю функцію, щоб відмовити дочірній VC використовувати цю функцію

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

якщо ви зателефонували до ДЦП за допомогою методу push, щоб звільнити дитину від ВК, скористайтеся цим

self.navigationController?.popViewController(animated: true)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.