Отобразить UIViewController как всплывающее окно на iPhone

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

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

enter image description here

Apple предоставляет несколько похожих UIViewController, таких как UIAlertView, Twitter или Facebook share view controller и т.д.

Как мы можем добиться этого эффекта для пользовательского контроллера?

Ответ 1

ПРИМЕЧАНИЕ. Это решение нарушено в iOS 8. Я опубликую новое решение как можно скорее.

Я собираюсь ответить здесь, используя раскадровку, но это также возможно без раскадровки.

  • Init: Создайте два UIViewController в раскадровке.

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

  • Модальное Segue: Поместите UIButton в FirstViewController и создайте segue на этом UIButton до SecondViewController как модальный сегмент.

  • Сделать прозрачным: Теперь выберите UIView (UIView который создан по умолчанию с UIViewController) SecondViewController и измените его цвет фона, чтобы очистить цвет.

  • Сделать фоновое изображение Dim: Добавить UIImageView в SecondViewController, который покрывает весь экран и устанавливает его изображение в какое-то полутемное полупрозрачное изображение. Вы можете получить образец отсюда: UIAlertView Фоновое изображение

  • Дизайн дисплея: Теперь добавьте UIView и создайте любой дизайн, который вы хотите показать. Вот скриншот моей раскадровки storyboard

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

    [self setModalPresentationStyle:UIModalPresentationCurrentContext];

  • Отклонить:. Когда отклонение зависит от вашего варианта использования. Это модальная презентация, поэтому, чтобы отклонить, мы делаем то, что делаем для модальной презентации:

    [self dismissViewControllerAnimated:YES completion:Nil];

Вот и все.....

Любые предложения и комментарии приветствуются.

Демо: Вы можете получить проект демо-проекта отсюда: Всплывающее демо

NEW. Кто-то проделал очень хорошую работу над этой концепцией: 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];
    }
}

Можно использовать этот метод внутри prepareForSegue, как это сделать

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

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

Ответ 2

Модальные всплывающие окна в построителе интерфейса (раскадровки)

Шаг 1

На ViewController, который вы хотите использовать в качестве своего модального всплывающего окна, сделайте фоновый цвет корневого UIView ясным. Установить очистить цвет в корневом представлении Совет. Не используйте корневой UIView в качестве своего всплывающего окна. Добавьте новый UIView, который меньше вашего всплывающего окна.

Шаг 2

Создайте Segue в ViewController, у которого есть всплывающее окно. Выберите "Показывать по-настоящему". Segue

Два метода создания всплывающего окна отсюда

Метод первый - использование Segue

Выберите Segue и измените презентацию на "Over Current Context": За текущий контекст

Метод второй - с помощью контроллера просмотра

Выберите сцену ViewController, которая является вашим всплывающим окном. В Инспекторе атрибутов в разделе "Контроллер просмотра" установите "Презентация" в "Контекст по текущему контенту": ViewController

Любой из этих методов будет работать. Это должно сделать это!

Готовый продукт

Ответ 3

Это можно сделать в Interface Builder.

  • Для представления, которое вы хотите представить, установите его внешний вид фона на прозрачный.
  • Control + щелчок и перетаскивание с контроллера представления хоста на контроллер модального представления.
  • Выберите текущий модальный
  • Нажмите на вновь созданный сегмент и в Инспекторе атрибутов (справа) установите "Презентация" в "Контекст по текущему контенту".

Ответ 4

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

Вы также можете попробовать новейшую версию MZFormSheetController, которая называется MZFormSheetPresentationController и имеет множество дополнительных функций.

Ответ 5

Вы можете использовать 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)

Ответ 6

Вы можете сделать это, чтобы добавить любое другое подзору в контроллер вида. Сначала установите для строки состояния значение None для 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];
}

Надеюсь, что это поможет, не стесняйтесь спрашивать, есть ли какие-либо вопросы...

Ответ 7

Imao поместить UIImageView на фоне - это не лучшая идея. В моем случае я добавил на контроллер два других вида. Первый вид имеет [UIColor clearColor] на фоне, второй - цвет, который должен быть прозрачным (серый в моем случае). Обратите внимание, что порядок важен. Затем для второго представления установите alpha 0.5 (alpha >= 0 <= 1).Added это для строк в prepareForSegue

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

И все.

Ответ 8

Свифт 4:

Чтобы добавить наложение или всплывающее представление. Вы также можете использовать представление " Контейнер", с помощью которого вы получаете бесплатный контроллер представления (вы получаете представление "Контейнер" из обычной палитры/библиотеки объектов).

enter image description here

шаги:

  1. Имейте представление (ViewForContainer на рисунке), которое содержит это представление контейнера, чтобы затемнить его при отображении содержимого представления контейнера. Подключите розетку внутри первого View Controller

  2. Скрыть этот вид при загрузке 1-го ВК

  3. Показать, когда кнопка нажата enter image description here

  4. Чтобы затемнить это представление при отображении содержимого представления контейнера, установите для фона видов черный цвет, а для непрозрачности - 30%.

enter image description here

Вы получите этот эффект, когда нажмете кнопку enter image description here