Представити та відхилити модальний контролер подання


77

Хто-небудь може дати мені приклад коду, за допомогою якого я можу спочатку представити контролер модального перегляду, а потім відхилити його? Це те, що я намагався:

NSLog(@"%@", blue.modalViewController);
[blue presentModalViewController:red animated:YES];
NSLog(@"%@", blue.modalViewController);
[blue dismissModalViewControllerAnimated:YES];
NSLog(@"%@", blue.modalViewController);

Цей код знаходиться в viewDidLoad ("синій" та "червоний" - це підкласи UIViewController). Я сподіваюся, що я покажу червоний вигляд, а потім негайно сховаю його, з деякою анімацією. Однак цей фрагмент коду лише представляє модальний вигляд і не відкидає його. Будь-яка ідея? Перший журнал показує "нуль", а два інших журнали<RedViewController: 0x3d21bf0>

Інший момент полягає в тому, що якщо я поміщу цей код у applicationDidFinishLaunching: червоний вигляд взагалі не відображається, і всі журнали отримують "нуль"


Як хтось каже нижче, presentModalViewController:animated:застарілий. Тепер вам потрібно використовувати presentModalViewController:animated:completion:та виконати наступні операції в блоці завершення (якщо ви хочете зачекати, поки не redбуде представлено). У будь-якому випадку, прочитайте статтю, яку пропонує @MatterGoal: developer.apple.com/library/ios/#featuredarticles/… .
Ферран Мейлінч,

Відповіді:


109

Перш за все, коли ви розміщуєте цей код у applicationDidFinishLaunching, може бути так, що контролери, створені за допомогою Interface Builder, ще не пов'язані з вашим додатком (тому "червоний" та "синій" все ще залишаються nil).

Але щоб відповісти на ваше початкове запитання, ви робите неправильно, це те, що ви телефонуєте не dismissModalViewControllerAnimated:на той контролер! Це має бути так:

[blue presentModalViewController:red animated:YES];
[red dismissModalViewControllerAnimated:YES];

Зазвичай "червоний" контролер повинен вирішити звільнити себе в якийсь момент (можливо, коли натискається кнопка "скасувати"). Тоді "червоний" контролер міг викликати метод на self:

[self dismissModalViewControllerAnimated:YES];

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


58
Згідно з посібником програмування View Controller для ОС iPhone, це неправильно, коли йдеться про відхилення модальних контролерів перегляду, яким слід використовувати делегування. Отже, перед тим, як представити свій модальний вигляд, зробіть себе делегатом, а потім зателефонуйте делегату з контролера модального подання, щоб звільнити.
Оскар Гомес

1
Пам'ятайте, що з io6 цей спосіб представлення модального вигляду знецінений. Використання: [self presentViewController: анімоване: завершення:]; натомість
simon_smiley

5
@OscarGomez Ні, керівництво з програмування контролера перегляду не говорить, що такий підхід є неправильним. У ньому сказано, що запропонований вами підхід є «переважним підходом». Іншими словами, хоча ваш підхід може працювати в багатьох ситуаціях, це не єдиний підхід, а лише той, який слід спробувати спочатку. Я пропоную вам додати підхід, який ви цитуєте, як додаткову відповідь, оскільки на таке запитання існує кілька життєздатних відповідей, і для деяких читачів ваш може бути кращим.
Slipp D. Thompson

4
[self dismissModalViewControllerAnimated:YES];застаріло
alternatiph

У чому різниця між викликом dismissModalViewControllerAnimatedна redабо blue? З документації здається, що нам слід це зателефонувати blue(представляючи VC) ...
Ферран Мейлінч

18

Стрімкий

Оновлено для Swift 3

введіть тут опис зображення

Розкадровка

Створіть два контролери подання з кнопкою на кожному. Для другого контролера перегляду встановіть для класу ім’я SecondViewControllerта ідентифікатор розкадровки secondVC.

Код

ViewController.swift

import UIKit
class ViewController: UIViewController {

    @IBAction func presentButtonTapped(_ sender: UIButton) {
        
        let storyboard = UIStoryboard(name: "Main", bundle: nil)
        let myModalViewController = storyboard.instantiateViewController(withIdentifier: "secondVC")
        myModalViewController.modalPresentationStyle = UIModalPresentationStyle.fullScreen
        myModalViewController.modalTransitionStyle = UIModalTransitionStyle.coverVertical
        self.present(myModalViewController, animated: true, completion: nil)
    }
}

SecondViewController.swift

import UIKit
class SecondViewController: UIViewController {
    
    @IBAction func dismissButtonTapped(_ sender: UIButton) {
        self.dismiss(animated: true, completion: nil)
    }
}

Джерело:


13

Найпростіший спосіб, яким я втомився в xcode 4.52, - це створити додатковий вигляд та з’єднати їх, використовуючи segue modal (керування перетягуванням кнопки з перегляду один на другий вигляд, вибраний Modal). Потім перетягніть кнопку до другого подання або модального подання, яке ви створили. Керуйте та перетягуйте цю кнопку у файл заголовка та використовуйте з’єднання дії. Це створить IBaction у вашому файлі controller.m. Знайдіть у коді тип дії кнопки.

[self dismissViewControllerAnimated:YES completion:nil];

Зверніть увагу, що це автоматично пересилає повідомлення на self.presentingViewController(згідно з документацією UIViewController), тому для ясності краще зателефонувати[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
Hatchmaster J

9

presentModalViewController:

MainViewController *mainViewController=[[MainViewController alloc]init];
[self.navigationController presentModalViewController:mainViewController animated:YES];

dismissModalViewController:

[self dismissModalViewControllerAnimated:YES];

3

Найпростіший спосіб це зробити, використовуючи Storyboard і Segue.

Просто створіть Segue із FirstViewController (а не Навігаційного контролера) вашого TabBarController до LoginViewController з інтерфейсом для входу та назвіть його "showLogin".

Створіть метод, який повертає BOOL для перевірки, якщо користувач увійшов у систему та / або його / її сеанс є дійсним ... бажано в AppDelegate. Назвіть це isSessionValid.

На вашому FirstViewController.m перевизначте метод viewDidAppear наступним чином:

- (void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];

    if([self isSessionValid]==NO){
        [self performSegueWithIdentifier:@"showLogin" sender:self];
    }
}

Тоді, якщо користувач успішно ввійшов у систему, просто відхиліть або відкрийте спливаюче вікно LoginViewController, щоб показати ваші вкладки.

Працює на 100%!

Сподіваюся, це допоможе!


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