Стилизация пользовательского интерфейса под iOS 5

в 8:50, , рубрики: ios 5, ios app, интерфейсы, разработка, разработка под iOS

Для успеха в App Store, ваше приложение должно выделяться, не быть похожим на другие. Пользовательский интерфейс и “look and feel”, разработанные Apple и доступные программерам по умолчанию уже совсем не смотрятся на перенаселенном рынке.

Многие из наиболее популярных приложений в App Store стилизуют стандартные элементы пользовательского интерфейса:
— Twitter использует стилизованный UITabBar
— Instagram – стилизованные UITabBar и UINavigationBar
— Epicurious для iPad перенастраивает внешний вид элементов стандартного интерфейса для split-view

До выхода iOS 5, многим программистам приходилось прибегать к несколько нестандартным мерам, чтобы достичь таких результатов. Хотя использование подклассов с переопределением drawRect: было рекомендуемым подходом к изменению внешнего вида интерфейса, многие прибегали к “method swizzling”.

Но с выходом iOS 5, те темные времена ушли в прошлое! iOS 5 включает в себя множество новых API, которые вы можете использовать для легкой и непринужденной настройки внешнего вида многих элементов, доступных в UIKit.

Для иллюстрации нового API мы возьмем простое приложение о курортах для серфинга, написанное безо всяких новшеств и излишеств только с использованием стандартного пользовательского интерфейса, и превратим его в нечто более “пляжно” выглядящее.

Стилизация пользовательского интерфейса под iOS 5

Для того, чтобы получить максимальную отдачу от этого урока, вы должны знать основы разработки под iOS. Если вы полный новичок, вам следует ознакомиться сначала c другими уроками на этом сайте.

Итак, в путь…

Для начала, скачайте проект. Это – простое приложение, которое позволит нам сразу перейти к главной теме нашего урока — стилизации UIKit интерфейса.
Откройте проект в XCode и просмотрите код и XIB файлы. Первый экран представляет собой список курортов для серфинга, а второй отображает детальную информацию о выбранном курорте.
Попробуйте запустить приложение (кликните Build & Run или нажмите Cmd-R), чтобы увидеть с чего мы собираемся начать.

Стилизация пользовательского интерфейса под iOS 5

Гм… Конечно, приложение работает, как было обещано, но интерфейс явно не доносит до пользователя и малой доли того кайфа, который они вправе ожидать от серфинговых курортов. Давайте посмотрим что с этим всем можно сделать, чтобы исправить ситуацию.

Начнем с экрана с деталировкой выбранного курорта. Все на экране выглядит стандартно. Даже слишком стандартно.
Незамысловатый UIBarButtonItem на стандартном UINavigationBar наверху. Элементы UITabBar из Эпплэвского набора внизу. Опять же стандартные компоненты для ввода данных:

— UILabels с “System” Helvetica фонтом.
— UITextField
— UISlider
— UISwitch
— UISegmentedControl

Далее мы полностью перестилизуем этот экран, используя новые API предоставляемые iOS 5.
Итак, вооруженные этими благими намерениями, давайте превратим наше приложение из нуля в единицу (что, в двоичном мире, есть большая разница).

Добавление фонового изображения

Если вы заглянете в директорию Images в вашем проекте, вы обнаружите, что мы уже подготовили там несколько файлов с графикой, которые мы сможем использовать для стилизации интерфейса. Нам остается только подправить код приложения, чтобы эта графика начала работать.

В директории присутствует файл bg_sand.png, который мы и используем как фон для нашего экрана.
Откройте DetailViewController.m в проекте и создайте метод viewDidLoad:

- (void)viewDidLoad {    
    [super viewDidLoad];
 
    [[self view] setBackgroundColor:[UIColor colorWithPatternImage:[UIImage imageNamed:@"bg_sand"]]];    
}

Если вы еще не знакомы с такой техникой установки фонового изображения, суть ее в том, что вы можете определить цвет фона как… картинку (что мы здесь и делаем). Мы используем этот трюк для установки фона UIView, т.к. у класса UIView нет property под названием “backgroundImage”, зато есть property под названием “backgroundColor”. И это работает!

Теперь запустите приложение, чтобы проверить, что новый код работает:

Стилизация пользовательского интерфейса под iOS 5
Я уже чувствую песок под… вашими ногами!

Стилизация для UINavigationBar

Среди графических файлов вы найдете файлы surf_gradient_textured_32.png и surf_gradient_textured_44.png, которые мы будем использовать для стилизации навигационной панели (в дальнейшем для краткости мы будем называть ее просто навигатором). Картинки в файлах отличаются высотой, т.к. в альбомной ориентации, навигатор должен быть уже.

Мы будем отрисовывать навигатор, повторяя картинку слева направо пока не покроем всю панель.

iOS 5 предоставляет два новых API, которые помогут нам осуществить задуманное:

— У UINavigationBar появилась новая property backgroundImage, которую мы будем использовать для отрисовки наших картинок.
— У UIImage появился новый метод resizableImageWithCapInsets для создания растяжимых изображений. “CapInsets” в названии метода определяет части изображения, которые должны отображаться только один раз (не повторяться). Примером могут служить закругленные углы кнопок, которые отображаются только по краям и не участвуют в отрисовке “тела” кнопки.

Мы могли бы поместить код, стилизующий навигатор с помощью новых API, прямо в контроллер, ответственный за отрисовку текущего экрана. Но тогда нам пришлось бы копировать этот код в контроллеры всех экранов приложения, чтобы навигатор выглядел везде одинаково. Такая стилизация, очевидно, далека от идеала.

По-счастью, iOS 5 предлагает новую концепцию “appearance proxy” (прокси внешнего вида), которая позволяет настроить интерфейс один раз и распространить эти изменения на все приложение.

Начиная с навигатора, мы будем использовать “appearance proxy” для настройки ряда повторяющихся элементов пользовательского интерфейса. Давайте посмотрим во что нам станет такой подход к проблеме.

В SurfsUpAppDelegate.m, создайте новый метод прямо над методом application:didFinishLaunchingWithOptions:

- (void)customizeAppearance
{
    // Создаем растяжимые изображения
    UIImage *gradientImage44 = [[UIImage imageNamed:@"surf_gradient_textured_44"] 
        resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
    UIImage *gradientImage32 = [[UIImage imageNamed:@"surf_gradient_textured_32"] 
        resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
 
    // Устанавливаем фоновые изображение для ВСЕХ UINavigationBars навигаторов
    [[UINavigationBar appearance] setBackgroundImage:gradientImage44 
        forBarMetrics:UIBarMetricsDefault];
    [[UINavigationBar appearance] setBackgroundImage:gradientImage32 
        forBarMetrics:UIBarMetricsLandscapePhone];
 
    // Стилизуем текст для заголовков ВСЕХ UINavigationBars навигаторов
    [[UINavigationBar appearance] setTitleTextAttributes:
        [NSDictionary dictionaryWithObjectsAndKeys:
            [UIColor colorWithRed:255.0/255.0 green:255.0/255.0 blue:255.0/255.0 alpha:1.0], 
            UITextAttributeTextColor, 
            [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8], 
            UITextAttributeTextShadowColor, 
            [NSValue valueWithUIOffset:UIOffsetMake(0, -1)], 
            UITextAttributeTextShadowOffset, 
            [UIFont fontWithName:@"Arial-Bold" size:0.0], 
            UITextAttributeFont, 
            nil]];
 
}

Первые две строчки создают растяжимую картинку с помощью метода resizableImageWithCapInsets, представленного выше. Обратите внимание, что этот метод в iOS5 заменил теперь устаревший метод stretchableImageWithLeftCapWidth:topCapHeight:.

Для “CapInsets” (тоже см. выше), вы обычно будете указывать размеры областей на вашей картинке (отступы в пикселах сверху, слева, снизу и справа), которые не подлежат растяжению (размножению). Все, что выпадает за пределы этих областей, будет растянуто по региону, для которого вы устанавливаете фоновую картинку. В нашем случае, мы хотим растянуть все изображение без исключений, и следовательно, устанавливаем все “CapInsets” в 0.

Следующие две строчки вызывают методы “appearance proxy”, устанавливая только что созданные нами растяжимые картинки как фоновые изображения для навигатора. Ориентация экрана, для которой устанавливается фон, указывается в параметре “forBarMetrics:”.

Последняя строка стилизует заголовок навигатора. Для этого мы используем NSDictionary c набором атрибутов для текста заголовка. Доступные ключи для атрибутов указаны ниже:

— UITextAttributeFont
— UITextAttributeTextColor
— UITextAttributeTextShadowColor
— UITextAttributeTextShadowOffset

Почти готово. Осталось добавить одну строчку с вызовом нового метода в самом начале метода application:didFinishLaunchingWithOptions:

[self customizeAppearance];

Скомпилируйте и запустите приложение. Вы должны увидеть в обеих ориентациях навигатор цвета морской волны со стилизованным заголовком!

Стилизация пользовательского интерфейса под iOS 5

Стилизация для UIBarButtonItem

Найдите в директории Images файлы button_textured_24.png и button_textured_30.png. Мы собираемся использовать их, чтобы стилизовать кнопки на навигаторе (UINavigationBar).

Для кнопок мы опять будем использовать растяжимые изображения. Это важно, т.к. ширина кнопок может меняться в зависимости от длины текста, размещенного на них.

Для кнопок первые и последние 5 пикселов не должны участвовать в растяжении, чтобы сформировать симпатичные закругленные левую и правую стороны. Так что мы установим соответствующие значения “CapInsets” в 5. Пикселы между этими границами будут повторены столько раз, сколько необходимо, чтобы закрасить всю ширину кнопки.

Давайте попробуем это сделать! Мы снова, как и в предыдущей главе, будем использовать “appearance proxy”, чтобы стилизовать сразу все кнопки UIBarButtonItems в нашем приложении.

Добавьте следующий код в конец метода customizeAppearance:

UIImage *button30 = [[UIImage imageNamed:@"button_textured_30"] 
    resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
UIImage *button24 = [[UIImage imageNamed:@"button_textured_24"] 
    resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 5)];
[[UIBarButtonItem appearance] setBackgroundImage:button30 forState:UIControlStateNormal 
    barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackgroundImage:button24 forState:UIControlStateNormal 
    barMetrics:UIBarMetricsLandscapePhone];
[[UIBarButtonItem appearance] setTitleTextAttributes:
    [NSDictionary dictionaryWithObjectsAndKeys:
        [UIColor colorWithRed:220.0/255.0 green:104.0/255.0 blue:1.0/255.0 alpha:1.0], 
        UITextAttributeTextColor, 
        [UIColor colorWithRed:1.0 green:1.0 blue:1.0 alpha:1.0], 
        UITextAttributeTextShadowColor, 
        [NSValue valueWithUIOffset:UIOffsetMake(0, 1)], 
        UITextAttributeTextShadowOffset, 
        [UIFont fontWithName:@"AmericanTypewriter" size:0.0], 
        UITextAttributeFont, 
        nil] 
    forState:UIControlStateNormal];

Все здесь уже выглядит знакомо. Мы создаем растяжимые изображения и устанавливаем их как фон для кнопок в обеих ориентациях экрана (портретной и альбомной). Затем мы форматируем фонт для текста на кнопках, чтобы он соответствовал стилю фонта (typewriter), который вы видели на картинках в самом начале урока.

Кнопка “back” на навигаторе требует специального подхода при стилизации, т.к. она должна выглядеть несколько по-другому – указывать назад. Взгляните на картинки, которые мы собираемся использовать для этого, чтобы лучше понять что здесь имеется ввиду: Imagesbutton_back_textured_24.png и Imagesbutton_back_textured_30.png.

Добавьте следующий код в конец метода customizeAppearance для стилизации кнопки “back” на навигаторе:

UIImage *buttonBack30 = [[UIImage imageNamed:@"button_back_textured_30"] 
    resizableImageWithCapInsets:UIEdgeInsetsMake(0, 13, 0, 5)];
UIImage *buttonBack24 = [[UIImage imageNamed:@"button_back_textured_24"] 
    resizableImageWithCapInsets:UIEdgeInsetsMake(0, 12, 0, 5)];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:buttonBack30 
    forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UIBarButtonItem appearance] setBackButtonBackgroundImage:buttonBack24 
    forState:UIControlStateNormal barMetrics:UIBarMetricsLandscapePhone];

Обратите внимание, что мы использовали другие значения для “CapInsets” потому, что у кнопки “back” левая сторона, которая не должна участвовать в растяжении, шире, чем у обычной кнопки. Также обратите внимание, что мы используем специальную property UIBarButtonItem под названием “backButtonBackgroundImage”.

Запустите приложение, и вы увидите отменные стилизованные кнопки UIBarButtonItems на вашем навигаторе!
Стилизация пользовательского интерфейса под iOS 5

Стилизация для UITabBar

Для стилизации UITabBar, iOS 5 предлагает API для изменения фонового изображения самого UITabBar, а также изображения, которое используется для выделения выбранного элемента (таба, или закладки – как вам привычнее). В качестве этих изображений мы будем использовать картинки из файлов Imagestab_bg.png и Imagestab_select_indicator.png. Потратьте пару минут, чтобы взглянуть на них.

Хотя наш прототип приложения использует только один UITabBar, мы могли бы решить добавить еще один-два позже. Наиболее вероятно, что в этом случае мы бы стилизовали их всех точно так же, как этот наш первый. Так что, мы опять попользуем “appearance proxy” подход, чтобы стилизовать все UITabBar в нашем приложении одинаково.

Добавьте следующий код в конец метода customizeAppearance:

UIImage *tabBackground = [[UIImage imageNamed:@"tab_bg"] 
    resizableImageWithCapInsets:UIEdgeInsetsMake(0, 0, 0, 0)];
[[UITabBar appearance] setBackgroundImage:tabBackground];
[[UITabBar appearance] setSelectionIndicatorImage:
        [UIImage imageNamed:@"tab_select_indicator"]];

Скомпилируйте и запустите опять… Прекрасно! Фон для UITabBar и картинка для выбранного элемента будут достойным добавлением к нашему интерфейсу.
Стилизация пользовательского интерфейса под iOS 5
Обратите внимание, что вы также можете указать “finished” и “unfinished” картинки, если вы хотите изменить способ появления изображений для выбранного и не выбранных элементов на UITabBar.

Стилизация для UISlider

Откройте файлы Imagesslider_minimum.png, Imagesslider_maximum.png и Imagesthumb.png, чтобы ознакомиться с картинками, которые мы будем использовать для стилизации UISlider.

iOS 5 делает стилизацию UISlider до неприличия простой – достаточно просто установить 3 property для UISlider: “maximumTrackImage”, “minimumTrackImage” и “thumbImage”.

Давайте попробуем. Добавьте следующий код в конец метода customizeAppearance:

UIImage *minImage = [[UIImage imageNamed:@"slider_minimum.png"] 
    resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 0)];
UIImage *maxImage = [[UIImage imageNamed:@"slider_maximum.png"] 
    resizableImageWithCapInsets:UIEdgeInsetsMake(0, 5, 0, 0)];
UIImage *thumbImage = [UIImage imageNamed:@"thumb.png"];
[[UISlider appearance] setMaximumTrackImage:maxImage 
    forState:UIControlStateNormal];
[[UISlider appearance] setMinimumTrackImage:minImage 
    forState:UIControlStateNormal];
[[UISlider appearance] setThumbImage:thumbImage 
    forState:UIControlStateNormal];

Скомпилируйте, запустите и насладитесь своим классным, стильным слайдером!
Стилизация пользовательского интерфейса под iOS 5

Стилизация для UISegmentedControl

Теперь мы займемся стилизацией UISegmentedControl (или просто сегментного переключателя). Стилизация этого компонента слегка сложнее, поскольку нам нужны фоновые картинки для включенного и выключенного состояния, а также отрисовка всевозможных комбинаций (т.е. вкл. слева/выкл. справа, выкл. слева/вкл. справа, выкл. на обеих сторонах).

Взгляните на картинки, чтобы вышесказанное стало яснее: Imagessegcontrol_sel.png, Imagessegcontrol_uns.png, Imagessegcontrol_sel-uns.png и Imagessegcontrol_uns-uns.png.

Затем, добавьте следующий код в конец метода customizeAppearance:

UIImage *segmentSelected = 
    [[UIImage imageNamed:@"segcontrol_sel.png"] 
        resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
UIImage *segmentUnselected = 
    [[UIImage imageNamed:@"segcontrol_uns.png"] 
        resizableImageWithCapInsets:UIEdgeInsetsMake(0, 15, 0, 15)];
UIImage *segmentSelectedUnselected = 
    [UIImage imageNamed:@"segcontrol_sel-uns.png"];
UIImage *segUnselectedSelected = 
    [UIImage imageNamed:@"segcontrol_uns-sel.png"];
UIImage *segmentUnselectedUnselected = 
    [UIImage imageNamed:@"segcontrol_uns-uns.png"];
[[UISegmentedControl appearance] setBackgroundImage:segmentUnselected 
    forState:UIControlStateNormal barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setBackgroundImage:segmentSelected 
    forState:UIControlStateSelected barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentUnselectedUnselected 
    forLeftSegmentState:UIControlStateNormal 
    rightSegmentState:UIControlStateNormal 
    barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] setDividerImage:segmentSelectedUnselected 
    forLeftSegmentState:UIControlStateSelected 
    rightSegmentState:UIControlStateNormal 
    barMetrics:UIBarMetricsDefault];
[[UISegmentedControl appearance] 
    setDividerImage:segUnselectedSelected 
    forLeftSegmentState:UIControlStateNormal 
    rightSegmentState:UIControlStateSelected 
    barMetrics:UIBarMetricsDefault];

Скомпилируйте, запустите и ваш UISegmentedControl приобретет совершенно иной вид!
Стилизация пользовательского интерфейса под iOS 5

Стилизация для UISwitch

На момент написания этого урока нет простого способа стилизации фонового изображения для UISwitch. Однако (как и для многих других элементов) очень легко поменять его цвет через property tintColor.

Чтобы продемонстрировать различные подходы к стилизации, мы в этот раз поменяем в нашем коде параметр “onTintColor”. Обратите внимание, что мы уже заранее подключили IBOutlet с именем rentSwitch в DetailViewController к нашему элементу UISwitch в DetailView.xib.

Так что просто добавьте следующий код для изменения цвета подкраски в метод viewDidLoad в DetailViewController:

[rentSwitch setOnTintColor:[UIColor colorWithRed:0 green:175.0/255.0 blue:176.0/255.0 alpha:1.0]];

Запустите приложение и оцените новый, свежеподкрашенный UISwitch!
Стилизация пользовательского интерфейса под iOS 5
Все теперь выглядит очень даже неплохо, но у нас осталась еще пара неохваченных элементов интерфейса. Нам надо научиться стилизовать ярлыки (labels) и изменять фон для UITextField.

Стилизация для UILabel

Ярлык – один из элементов на нашем экране, который мы НЕ будем стилизовать через “appearance proxy”. Откройте DetailView.xib, и мы изменим их вид прямо в Interface Builder. Сначала на основном экране в Interface Builder выберите первый ярлык (т.е “Your name”). Затем, на правой панели зайдите в Attributes Inspector и поменяйте следующие атрибуты:

Font: Custom
Family: American Typewriter
Style: Regular
Size: 16

Повторите то же для остальных ярлыков: “Experience Level” и “Rent a board?”.

Скомпилируйте и запустите приложение. Теперь текст на ярлыках прорисовывается новым, аккуратным, симпатичным шрифтом!
Стилизация пользовательского интерфейса под iOS 5

Стилизация для UITextField

Наш UITextField элемент уже использует UITextBorderStyleLine стиль. Поскольку мы все еще в Interface Builder, давайте установим для него новый фонт: American Typewriter, Size 12, Regular.

Если вы загляните в Identity Inspector, вы увидите, что в поле Custom Class, класс для нашего поля определен не как UITextField, а как CustomTextField. В навигаторе проекта (левая панель) откройте группу с названием Custom Views. В этой группе мы уже создали класс с таким же именем – CustomTextField.

Пока метод drawRect: нашего UITextField делегирует всю прорисовку супер-классу. Но для того, чтобы закрасить фон цветом морской волны, нам прийдется переопределить этот метод (что есть не что иное, как еще одна техника стилизации).

Замените вызов супер-класса на следующий код:

- (void)drawRect:(CGRect)rect
{
    UIImage *textFieldBackground = [[UIImage imageNamed:@"text_field_teal.png"] resizableImageWithCapInsets:UIEdgeInsetsMake(15.0, 5.0, 15.0, 5.0)];
    [textFieldBackground drawInRect:[self bounds]];
}

Здесь мы создаем уже знакомое нам растяжимое изображение с подходящими значениями “CapInsets” и зарисовываем им прямоугольную область нашего UITextField.

Давайте скомпилируем и посмотрим на результат…
Стилизация пользовательского интерфейса под iOS 5
Наши поздравления! Ваш экран полностью стилизован!

Автор: MicRaiS

Поделиться