- PVSM.RU - https://www.pvsm.ru -

UIAppearance. Управление внешним видом iOS-приложений

Стиль или Суть
Сообщение или Носитель
Риторика или Диалектика

Красота — это нечто поверхностное или же идущее из глубинных истин?
Что значит «хороший дизайн»?
Эстетические суждения относительны или абсолютны?

Это важные вопросы, которые обсуждались философами, художниками и поэтами на протяжении тысячелетий.

И пока мы продолжаем наши поиски красоты и понимания мира, рынок мобильных приложений в данной области однозначно утверждает:

Пользователи платят за красивые приложения.

При покупке iPhone, пользователь покупает также философию Apple: вещи должны не только хорошо работать, но и хорошо выглядеть. То же относится к разработке на iOS — некрасивый интерфейс пользователя сказывается и на программном коде.

Исторически даже для незначительного изменения внешнего вида приложения в iOS требовался набор хаков, сопряженных с опасностью отклонения приложения в AppStore. К счастью, начиная с iOS 5 у разработчиков есть новый инструмент: UIAppearance.

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

Для реализации этого с сохранением существующей структуры UIKit специалисты Apple реализовали достаточно интересное решение: UIAppearance — это протокол, предоставляющий прокси-объект, который используется для конфигурирования объектов конкретного класса. Почему именно прокси, а не свойство или метод самого UIView? Потому что существуют объекты, не входящие в иерархию UIView, такие как UIBarButtonItem, со своим собственным представлением. Внешний вид может быть изменен у всех компонентов определенного типа или только у привязанных к специфической иерархии:

  • +appearance возвращает прокси-объект для данного класса элементов.
  • +appearanceWhenContainedIn:(Class <UIAppearanceContainer>)ContainerClass,...: возвращает прокси-объект для объектов, находящихся в определенном контейнере.

Для управления внешним видом всех объектов класса, нужно использовать прокси-объект, связанный с этим классом. Например, чтобы изменить цвет всех объектов UINavigationBar:

[[UINavigationBar appearance] setTintColor:myColor];

Для того, чтобы изменить внешний вид объектов определенного класса в заданном контейнере — используйте метод appearanceWhenContainedIn::

[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], nil]
                               setTintColor:myNavBarColor];
[[UIBarButtonItem appearanceWhenContainedIn:[UINavigationBar class], [UIPopoverController class], nil]
                               setTintColor:myPopoverNavBarColor];
[[UIBarButtonItem appearanceWhenContainedIn:[UIToolbar class], nil]
                               setTintColor:myToolbarColor];
[[UIBarButtonItem appearanceWhenContainedIn:[UIToolbar class], [UIPopoverController class], nil]
                               setTintColor:myPopoverToolbarColor];

Определение свойств, доступных через UIAppearance

Важной проблемой работы UIAppearance через прокси является сложность определения списка методов, доступных для изменения. Поскольку +appearance возвращает id, Xcode не предоставляет соответствующую информацию при авто-подстановке.

Получить список методов, работающих с UIAppearance можно поиском по заголовочным файлам [1]:

$ cd /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS*.sdk/System/Library/Frameworks/UIKit.framework/Headers
$ grep -H UI_APPEARANCE_SELECTOR ./* |sed 's/ __OSX_AVAILABLE_STARTING(__MAC_NA,__IPHONE_5_0) UI_APPEARANCE_SELECTOR;//'

UIAppearance завязан на наличие макроса UI_APPEARANCE_SELECTOR в определении метода. Любой метод с подобной пометкой может быть использован при работе через прокси.

Вот, для удобства, список поддерживаемых свойств для iOS 6.1 [2]

Реализация UIAppearance в собственных компонентах

Подобно тому, как NSLocalizedString и #pragma являются признаками качества Objective-C кода, возможность управления внешним видом собственных UI компонентов через UIAppearance является не только рекомендуемой практикой, но также демонстрирует определенный уровень заботы создателя компонента при его реализации.

В этой статье [3] демонстрируются некоторые нюансы реализации UIAppearance в собственных компонентах. Она обязательна к прочтению для разработчиков, стремящихся создавать качественные UI компоненты.

Альтернативные решения

Потенциальным недостатком UIAppearance является то, что управление интерфейсом является императивным, а не декларативным, т.е. осуществляется во время выполнения программы, а не считывается из некого списка правил.

Это идея, пришедшая из веб-разработки — разделение содержимого и его представления. Что бы не говорилось про CSS, но таблицы стилей великолепно справляются с этой задачей.

Приверженцы таблиц стилей на iOS могут выбирать из нескольких альтернатив. Pixate [4] — коммерческий фреймворк, который использует CSS для стилизации приложений. NUI [5] — проект с открытым кодом, делает то же при помощи CSS/SCSS-подобного языка. Другой открытый проект той же направленности UISS [6] — позволяет настраивать UIAppearance при помощи JSON.

Cocoa-программисты всегда были одержимы визуальной эстетикой и часто впадали в крайности в попытке достичь желаемого эффекта. Достаточно вспомнить Восхитительное Поколение [7] Mac-разработчиков и приложения типа Disco [8], которое выпускало виртуальный дым при записи дисков [9].

Дух перфекционизма жив и в iOS. Сообщество постоянно развивает систему в сфере пользовательского взаимодействия. Это делает разработку под iOS более сложной, но и гораздо более приятной.

Не соглашайтесь на полумеры.
Делайте свои приложения прекрасными от внешнего вида до реализации.

Автор: nsemchenkov

Источник [10]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/ios/42865

Ссылки в тексте:

[1] по заголовочным файлам: http://stackoverflow.com/questions/9424112/what-properties-can-i-set-via-an-uiappearance-proxy

[2] список поддерживаемых свойств для iOS 6.1: https://gist.github.com/mattt/5135521

[3] этой статье: http://petersteinberger.com/blog/2013/uiappearance-for-custom-views/

[4] Pixate: http://www.pixate.com/

[5] NUI: https://github.com/tombenner/nui

[6] UISS: https://github.com/robertwijas/UISS

[7] Восхитительное Поколение: http://en.wikipedia.org/wiki/Delicious_Generation

[8] Disco: http://discoapp.com/

[9] выпускало виртуальный дым при записи дисков: http://www.youtube.com/watch?v=8Dwi47XOqwI

[10] Источник: http://habrahabr.ru/post/190858/