Дополнение к Лекции 7: Изменение адаптивности Popover в iOS 8.3

Эта тема важна для Лекции 7, в которой рассматривается Popover для iPhone и iPad, и для демонстрационного примера «Psychologist Popover«, который доступен на сайте  Stanford. Этот демонстрационный пример в части Popover  на iPhone будет работать в iOS 8.3 не так, как планировалось. Вариант исправленного демонстрационного примера «Psychologist Popover« для iOS 8.3 доступен на  Github. Ниже дается пояснение проблемы.

Адаптивность до  iOS 8.3

Само по себе Popover — не UIViewController. Он появляется на экране, используя так называемый механизм Presentation Controller. Popover на iPad “всплывает” так, как вы видели на рисунке выше для iOS 8.2. В виде маленького окошка со стрелкой. На iPhone Popover адаптируется и превращается вместо маленького окошка в модальное окно на полный экран. Оно не “всплывает” как что-то маленькое на iPhone. Что касается iPhone 6 Plus, то в портретном режиме он ведет себя как iPhone ( модальное окно на весь экран), а в ландшафтном режиме как iPad ( маленькое «всплывающее» окно). Такая Адаптация делается автоматически. iOS 8 автоматически делает эту адаптацию также, как автоматически адаптируется Split View и Navigation Controller для iPhone.
Перед iOS 8.3, Адаптивность Popover работала, когда горизонтальный size class изменяется от Regular к Compact.

Это означает, что система iOS 8 определяет AnyCompact не как обычную среду для Popover, а как нуждающуюся в адаптивном стиле презентации. Но используя делегата UIPopoverPresentationControllerDelegate, вы можете воздействовать на эту адаптацию и даже запретить ее, чтобы на любом приборе Popover работала как на iPad.

Для этого у делегата UIPopoverPresentationControllerDelegate есть метод

Screen Shot 2015-04-14 at 6.26.44 PM

, который позволяет изменить адаптивный стиль презентации. Более точно, он возвращается стиль презентации, используемый для случая, когда представляемый View Controller становится горизонтально Compact.

Нам достаточно использовать этот метод таким образом

Screen Shot 2015-04-14 at 6.29.15 PM
,чтобы на любом приборе Popover работала как на iPad.

Screen Shot 2015-04-14 at 7.42.21 PM
Но в в iOS 8.3 это не работает — результат вы видите на  рисунке внизу. Для iPhobe 6 Plus в iOS 8.3 в портретном режиме мы видим модальное окно на весь экран, а iPhobe 6 Plus в iOS 8.3 в портретном режиме мы видим также модальное окно, хотя и не на весь экран. Избавиться от этих модальных окон не удается.

Screen Shot 2015-04-14 at 6.38.23 PM

Новое в iOS 8.3

iOS 8.3 «думает» об Адаптации немного иначе, и это нужно принимать во внимание. Адаптивность больше не фокусируется исключительно на HorizontalSize в iOS 8.3. Для этого public API делегата UIAdaptivePresentationControllerDelegate (это superclass для UIPopoverPresentationControllerDelegate ) усилился новым методом:

Screen Shot 2015-04-14 at 7.13.29 PM

Заметьте, что появился дополнительный аргумент типа UITraitCollection. Теперь это означает, что мы можем решать, какие комбинации size class заслуживают адаптивного стиля.

«Засада» в iOS 8.3 Popover

Пример Popover выше был выбран неслучайно. Если вы создадите приложение в iOS 8.3 SDK с Popover, то заметите, что Popover теперь отображается на iPhone 6 Plus в ландшафтном режиме как FormSheet, то есть модально (смотри рисунок выше). Это совершенно неожиданно и неудобно. Воспользовавшись новым API, оказалось возможным вернуть приложение к правильному функционированию. Но также удалось обнаружить, что по умолчанию, UIPopoverPresentationController теперь выбирает адаптивный стиль .FormSheet для Regular-Compact среды. Хорошо, что у нас появился новый public API для этих новых вариантов адаптации, и мы можем его очень просто использовать

Screen Shot 2015-04-14 at 7.20.21 PM
Теперь нам удастся вернуться к нашему первому рисунку — на всех приборах во всех режимах будет правильный Popover.

Подводя итоги

Popover в iOS 8.2 в силу новой концепции «адаптивности» работает так, что на всех iPhone (кроме iPhone 6 Plus в ландшафтном режиме) будет представлять Popover как модальное окно на весь экран. Это если ничего не предпринимать. Popover в iOS 8.3 в силу концепции «адаптивности» все также будет работать плохо на iPhone, даже еще хуже, так как такое же модальное окно (правда не на весь экран) теперь будет и у iPhone 6 Plus в ландшафтном режиме. Если тоже ничего не предпринимать. Бороться с этим, если вы хотите на любом приборе «настоящий» Popover как на iPad, в  iOS 8.2 и iOS 8.3 нужно разными методами делегата UIPopoverPresentationControllerDelegate. Так как концепция «адаптивность» поменялась ( теперь она не нацелена на горизонтальный Compact) — поменялся и метод для «подавления» этой адаптивности.

Возможное будущее Адаптивности

С этим новым  API, Адаптивность больше не означает горизонтального Сompact. Я думаю, что новое определение Адаптивности Apple _not Regular– по обоим осям. Если один из size classes не являетсяi Regular, презентация нуждается в адаптации. В настоящий момент у нас два size classesCompact и Regular — но Apple в будущем может ввести еще больше size classes ( возможно, iPad Pro или Apple TV). Теперь мы можем думать о  Any-Compact или Compact-Any как об адаптивных размерах, но мы должны настраиваться на Any-!Regular и !Regular-Any как адаптивные. Возможно, что в будущем будут приниматься во внимание не только малые TraitСollections, но и большие.

Материал основан на статье «Adaptability Changes in iOS 8.3».