Відобразити UIViewController як спливаюче вікно в iPhone


75

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

Часто нам потрібно подарувати UIViewControllerтакий, щоб він не охоплював весь екран, як на малюнку нижче.

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

Apple пропонує кілька подібних UIViewController, таких як UIAlertViewTwitter або Facebook, контролер спільного перегляду тощо.

Як ми можемо досягти цього ефекту для користувацького контролера?


10
Будь ласка, прокоментуйте, чому у вас немає голосу, щоб я міг покращитись.
CRD, винесено

Я б порадив вам використовувати STPopup Використовуйте його так само, як UINavigationController.
Кевін

Я знайшов цей стручок хорошим: github.com/huynguyencong/EzPopup
huync

Відповіді:


95

ПРИМІТКА. Це рішення не працює в iOS 8. Я опублікую нове рішення якомога швидше.

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

  1. Init: Створіть два UIViewControllerв раскадровці.

    • скажемо, FirstViewControllerщо є нормальним, а SecondViewControllerяке буде спливаючим.

  2. Модальний Segue: Покласти UIButtonв FirstViewController і створити SEGUE з цього питання UIButtonв SecondViewControllerякості модального Segue.

  3. Зробити прозорим: тепер виберіть UIView( UIViewЯкий створюється за замовчуванням із UIViewController) SecondViewControllerта змініть колір тла на чистий.

  4. Зробити фон Dim: Додати UIImageViewв SecondViewControllerякій охоплює весь екран і встановлює його зображення в будь - то потьмяніли напівпрозорого зображення. Ви можете отримати зразок тут: UIAlertViewФонове зображення

  5. Дизайн дисплея: Тепер додайте UIViewі зробіть будь-який дизайн, який ви хочете показати. Ось скріншот моєї розкадровки розкадровка

    • Тут я додаю кнопку segue на кнопку входу, яка відкривається у SecondViewControllerвигляді спливаючого вікна, щоб запитати ім’я користувача та пароль
  6. Важливо: Тепер цей головний крок. Ми хочемо, щоб SecondViewControllerце не приховувало FirstViewController повністю. Ми встановили чіткий колір, але цього недостатньо. За замовчуванням він додає чорний колір за презентацією моделі, тому нам потрібно додати один рядок коду в viewDidLoad of FirstViewController. Ви можете додати його в іншому місці, але він повинен працювати до початку сезону.

    [self setModalPresentationStyle:UIModalPresentationCurrentContext];

  7. Звільнення : Коли звільняти, залежить від вашого випадку використання. Це модальна презентація, тому для звільнення ми робимо те, що робимо для модальної презентації:

    [self dismissViewControllerAnimated:YES completion:Nil];

Це все.....

Будь-які пропозиції та коментарі вітаються.

Демо: Ви можете отримати демо-проект із тут: Popup Demo

НОВЕ : Хтось зробив дуже гарну роботу над цією концепцією: MZFormSheetController
Нове : Я знайшов ще один код для отримання такої функції: KLCPopup


Оновлення iOS 8 : Я зробив цей метод для роботи як з iOS 7, так і з iOS 8

+ (void)setPresentationStyleForSelfController:(UIViewController *)selfController presentingController:(UIViewController *)presentingController
{
    if (iOSVersion >= 8.0)
    {
        presentingController.providesPresentationContextTransitionStyle = YES;
        presentingController.definesPresentationContext = YES;

        [presentingController setModalPresentationStyle:UIModalPresentationOverCurrentContext];
    }
    else
    {
        [selfController setModalPresentationStyle:UIModalPresentationCurrentContext];
        [selfController.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];
    }
}

Ви можете використовувати цей метод всередині PrepaForSegue, наприклад, таким чином

- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {

    PopUpViewController *popup = segue.destinationViewController;
    [self setPresentationStyleForSelfController:self presentingController:popup]
}

1
Налаштування, [self setModalPresentationStyle:UIModalPresentationCurrentContext];здається, порушує анімацію модального переходу ( UIModalTransitionStyleCrossDissolveнаприклад) при презентації другого контролера перегляду, тому він просто з’являється без анімації. Будь-які думки, як це виправити?
filwag

@cevitcejbo Дякую, щоб поглянути. on segue, якщо ми встановимо властивість переходу на будь-яке, що дає анімацію, але лише тоді, коли відхилення не відображається. Поки я не знаю, як це вирішити. Я редагую свою відповідь, коли знаходжу. Якщо ви знайдете це, повідомте мені.
CRDave

5
@CRDave, як ви запропонували вище, [self setModalPresentationStyle:UIModalPresentationCurrentContext];не працює самостійно. Потрібно використовувати [self.navigationController setModalPresentationStyle:UIModalPresentationCurrentContext];також те, що зображено у вашому демо-проекті.
Васу

@Kailash Так, ви маєте рацію, якщо хтось використовував навігаційний контролер, ніж потрібно. Я написав це тут: github.com/Chintan-Dave/popupDemo/issues/1 . Дякуємо, що додали сюди.
CRDave

Як змінити правильність спливаючого вікна?
Govind

51

Модальні спливаючі вікна у конструкторі інтерфейсів (розкадрування)

Крок 1

На ViewController, який ви хочете використовувати як модальне спливаюче вікно, зробіть чітким колір тла кореневого UIView. Встановіть Clear Color у кореневому поданні Порада. Не використовуйте кореневий UIView як спливаюче вікно. Додайте новий UIView, розмір якого менше для вашого спливаючого вікна.

Крок 2

Створіть Segue для ViewController, що має ваше спливаюче вікно. Виберіть "Презентувати модально". Segue

Два методи створення спливаючого вікна звідси

Спосіб перший - Використання Segue

Виберіть Segue та змініть Презентацію на "Поточний контекст": Над поточним контекстом

Спосіб другий - Використання контролера перегляду

Виберіть сцену ViewController, яка є вашим спливаючим вікном. В Інспекторі атрибутів у розділі Контролер перегляду встановіть для Презентації значення «Поточний контекст»: ViewController

Будь-який метод буде працювати. Це має зробити це!

Закінчений продукт


Ось ще трохи допомоги, якщо я можу: Створіть у своєму коді клас контролера перегляду десь на зразок MyDialog: UIViewController. Встановіть його як спеціальний клас нового контролера перегляду в розкадруванні. Помістіть кнопки тощо та підключіть їх до свого коду за допомогою Control + Drag. Відхилення виклику (анімоване, завершення) після натискання кнопки.
Нуман Карааслан,

1
Це чудово .. Дякую
Ім Бетмен

13

Ви можете зробити це в Interface Builder.

  • Для подання, яке ви хочете представити, встановіть його зовнішній фон вигляду прозорим
  • Control + клацання та перетягування з головного контролера перегляду на модальний контролер перегляду
  • Виберіть подарунок модально
  • Клацніть на новостворену сегу та в Інспекторі атрибутів (праворуч) встановіть для «Презентація» значення «Над поточним контекстом»

10

Не соромтеся використовувати мій контролер аркуша форм MZFormSheetController для iPhone, у прикладі проекту є багато прикладів того, як представити контролер модального перегляду, який не охоплює повне вікно і має багато стилів презентації / переходу.

Ви також можете спробувати найновішу версію MZFormSheetController, яка називається MZFormSheetPresentationController, і має набагато більше можливостей.


цей контролер аркуша форми виглядає ВЕЛИКИМ, проблема полягає лише в тому, що, коли я представляю повноекранний модальний контролер подання, а потім відхиляю його, контролер аркуша форми також стане повноекранним. будь ласка, допоможіть
Mazen Kasser

немає необхідності знайти цей ваш зручний код;) // Для представлення MZFormSheetController * formSheet = [[MZFormSheetController alloc] initWithViewController: контролер]; [formSheet presentAnimated: ТАК завершенняHandler: nil]; // Відхилити MZFormSheetController * controller = self.navigationController.formSheetController; [контролер dismissFormSheetControllerAnimated: ТАК завершенняHandler: nil];
Mazen Kasser

2

Ви можете використовувати EzPopup ( https://github.com/huynguyencong/EzPopup ), це струм Swift і дуже простий у використанні:

// init YourViewController
let contentVC = ...

// Init popup view controller with content is your content view controller
let popupVC = PopupViewController(contentController: contentVC, popupWidth: 100, popupHeight: 200)

// show it by call present(_ , animated:) method from a current UIViewController
present(popupVC, animated: true)

1

Imao поставити UIImageView на задньому плані - не найкраща ідея. У моєму випадку я додав до перегляду контролера інші 2 подання. Перший вигляд має [UIColor clearColor]на фоні, другий - колір, який ви хочете бути прозорим (у моєму випадку сірим). Зверніть увагу, що порядок важливий. Тоді для другого вигляду встановіть альфа 0,5 (альфа> = 0 <= 1). Додано це до рядків уprepareForSegue

infoVC.providesPresentationContextTransitionStyle = YES;
infoVC.definesPresentationContext = YES;

І це все.


1

Свіфт 4:

Щоб додати накладення або спливаюче подання Ви також можете використовувати подання контейнера, за допомогою якого ви отримуєте безкоштовний контролер перегляду (вигляд контейнера ви отримуєте із звичайної палітри об’єктів / бібліотеки)

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

Кроки:

  1. Розмістіть подання (ViewForContainer на зображенні), яке містить цей вигляд контейнера, щоб затемнити його, коли відображається вміст перегляду контейнера. Підключіть розетку всередині першого контролера перегляду

  2. Сховати цей вигляд при завантаженні 1-го ВК

  3. Показати, коли натиснуто кнопку введіть тут опис зображення

  4. Щоб затемнити цей вигляд, коли відображається вміст "Перегляд контейнера", встановіть для "Тла переглядів" значення "Чорний" та непрозорість - 30%.

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

Цей ефект ви отримаєте, натиснувши кнопку введіть тут опис зображення


0

Це можна зробити, щоб додати будь-який інший підпрогляд до контролера перегляду. Спочатку встановіть для рядка стану значення Немає для ViewController, який ви хочете додати як підвигляд, щоб ви могли змінити розмір до потрібного. Потім створіть кнопку в контролері Present View і метод для натискання кнопки. У способі:

- (IBAction)btnLogin:(id)sender {
    SubView *sub = [[SubView alloc] initWithNibName:@"SubView" bundle:nil];
    sub.view.frame = CGRectMake(20, 100, sub.view.frame.size.width, sub.view.frame.size.height);
    [self.view addSubview:sub.view];
}

Сподіваюся, це допоможе, сміливо запитуйте, чи є запитання ...


Ось SubView - це UIViewController з інтерфейсом xib, а не під поданням
User-1070892

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