Дополнение к Лекциям 15, 16 и 17 Stanford CS 193P iOS 7. Адаптивный интерфейс с двумя storyboards для iOS 9.

Screen Shot 2016-01-25 at 11.38.41 AM

Концепция построения адаптивного пользовательского интерфейса начиная с iOS 8 сводится не только к применению механизма Autolayout, она буквально пронизывает все самые интересные элементы пользовательского интерфейса (UI) :  Split View Controllers, Popovers, Action Sheets,  модальные View Controllers. Теперь Split View Controllers и Popovers, можно использовать не только на iPad, но и на iPhone, они подстраиваются автоматически под размер и ориентацию прибора, а точнее под Size Classes. В них заложено по умолчанию адаптивное поведение для приборов с Compact размером, и вам вообще не нужно ничего специально настраивать. Но иногда такое адаптивном поведение может нам не понравиться. Например, Popover для iPhone работает как модальный View Controller, полностью оккупирующий весь экран. Если вас это не устраивает, то вы можете настроить его минимальными программными усилиями нужным вам образом, например, заставив функционировать Popover на iPhone так, как мы привыкли видеть его на iPad, то есть ввиде маленького всплывающего «окошка».

Идея создания адаптивного интерфейса сводится к тому, что можно использовать одну storyboard для проектирования пользовательского интерфейса для различных приборов и их ориентаций.  Мы видели это  в посте «Адаптивные интерфейсы SplitView Controller и Popover в iOS 9», где используются адаптивные свойства   Split View Controllers и Popovers.

Но количество приборов растет, вот уже и огромный iPad Pro появился. Поэтому трудно представить, что пользовательские интерфейсы для таких различающихся, по крайней мере, по размеру приборов, как iPad Pro и iPhone 4s, удастся  «запихнуть» в одну storyboard, пусть и с фантастической адаптацией.

Мне представился случай убедиться в этом на демонстрационном примере Photomania Map, который показывался на Лекции №15 стэнфордских курсов Developing iOS  7 Apps for iPhone and iPad в 2013-2014гг.

Приложение Photomania Map запрашивает сервис Flickr о последних по времени сделанных фотографиях, составляет список фотографов, кто сделал эти фотографии, и показывает вам список этих фотографов. Eсли вы кликните на фотографе, то вам покажут на карте, где были сделаны его фотографии . Затем вы можете кликнуть на красной «булавке», представляющий каждую отдельную фотографию на карте, и получить как полномасштабное изображение вашей фотографии, так и ее URL.

Это приложение в фоновом режиме (background) постоянно запрашивает Flickr о все большем и большем количестве последних фотографий и забрасывает их в базу данных Core Data.  Список фотографов на экране отслеживает появление этих данных. Смотрим фотографов, кликаем на них, смотрим их фотографии и все это будет автоматически обновляться постоянно. Вот какое приложение Photomania Map создается на Лекции 15 стэнфордского курса. Я не хочу останавливаться на деталях реализации, но важно отметить, что приложение спроектировано не только с существенно различными интерфейсами для iPhone и iPad, но эти интерфейсы еще обслуживаются и разными классами.

Это приложение было написано для iOS 7, наличие двух storyboards —  одной — для iPhone, а другой — для iPad — было в порядке вещей, и ни о каком адаптивном интерфейсе, кроме как использования механизма Autolayout, речь не шла.

Однако спроектированное таким образом приложение Photomania Map для iOS 7 не будет работать правильно на всех приборах в iOS 9: на iPhone 5s и более старших моделях и снизу, и сверху будет черная полоса на экране. Поэтому давайте рассмотрим, как создать современный адаптивный пользовательский интерфейс этого приложения для iOS 9.

Первое, что необходимо сделать — это сделать интерфейсы на обоих storyboards адаптивными, то есть включить опцию Size Class

Screen Shot 2016-01-25 at 10.41.57 AM

Для iPhone интерфейс построен на Navigation Controller

Screen Shot 2016-01-25 at 10.36.47 AM

Screen Shot 2016-01-25 at 7.37.00 AM

Для iPad интерфейс построен на Split View Controller  и Embeded Segue
Screen Shot 2016-01-24 at 7.34.37 PM

Screen Shot 2016-01-25 at 7.50.34 AM
Screen Shot 2016-01-25 at 7.51.06 AMДалее можно настроить появление Popover на iPhone в виде всплывающего маленького «окошка». Как это сделать описано в   в посте «Адаптивные интерфейсы SplitView Controller и Popover в iOS 9».

В iOS 9, когда Popover пытается провести презентацию, он спрашивает нас , как мы хотим, чтобы  Popover “адаптировался”, если мы находимся на приборах с Compact шириной (все iPhone, кроме iPhone 6+ и iPhone 6s+ в ландшафтном режиме)? По умолчанию — это модальное представление на полный экран. Но мы можем сказать, что мы не хотим никакой адаптации, и тогда презентация Popover на iPhone-подобных приборах с Compact шириной будет в точности такая же, как и на iPad. Для маленького Popover это имеет очень большой смысл. Ответить на вопрос о стиле презентации Popover на приборе с Compact шириной можно, реализовав метод adaptivePresentationStyleForPresentationController:traitCollection: делегата  UIPopoverPresentationControllerDelegate:
Screen Shot 2016-01-26 at 6.28.07 PM
Возврат UIModalPresentationFullScreen, означает, что презентация Popover будет проводиться на полный экран, то есть так, как принято по умолчанию.
Возврат UIModalPresentationNone означает, что мы “выключили” поведение “адаптации” и хотим, чтобы на  презентация Popover на iPhone-подобных приборах с Compact шириной будет в точности такая же, как и на iPad.
Подводя итоги, покажем, какие шаги нужно сделать, чтобы отменить «адаптивную» презентацию Popover на iPhone. Для этого необходимо сделать  представляемый View Controller (у нас это URLViewController) делегатом UIPopoverPresentationControllerDelegate и добавить дополнительный код:

1.  подтвердить реализацию протокола UIPopoverPresentationControllerDelegate 

Screen Shot 2016-01-30 at 7.46.46 AM

2.  в  методе awaikFromNib задать стиль презентации UIModalPresentationPopover и указать, что вы будете делегатом протокола UIPopoverPresentationControllerDelegate

Screen Shot 2016-01-30 at 7.50.47 AM
3. реализовать метод делегата adaptivePresentationStyleForPresentationController:traitCollection: 

Screen Shot 2016-01-26 at 6.28.07 PM

4. реализовать метод preferredContentSize (необязательно, но желательно для «подгонки» размера Popover к расположенному в нем контексту:

Screen Shot 2016-01-26 at 12.58.36 PM

 

Итак, оба интерфейса являются адаптивными и построены с учетом Size Classes. Теперь решающим значением для выбора между ними является размер экрана прибора iOS.

Как осуществить автоматическое переключение между ними?

В нашем универсальном приложении две storyboards: Main и Main_iPad (содержание их приведено выше)

Screen Shot 2016-01-25 at 8.29.30 AM

В PhotomaniaAppDelegate добавляем код для переключения между storyboards

Screen Shot 2016-01-25 at 11.27.08 AM
. . . . . . . . . . . . . . . . . . . .

Все очень просто, но теперь приложение будет правильно работать на всех приборах во всех ориентациях.

Код для адаптированного приложения Photomania Map для iOS 9 можно посмотреть на Github.