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

в 7:53, , рубрики: Appearance API, Cocoa, iOS, iphone development, objective-c, разработка под 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 можно поиском по заголовочным файлам:

$ 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

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

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

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

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

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

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

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

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

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

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

Автор: nsemchenkov

Источник


* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js