Pull to refresh

UIImage и resizableImageWithCapInsets

Reading time 2 min
Views 16K
Original author: John Muchow
Недавно я начал писать небольшой пример, чтобы лучше изучить iOS 5 Appearance API и кастомизацию UINavigationBar. Цель была в том, чтобы добавить собственный фон, заголовок и текст в панель навигации. Когда я его закончил, я решил улучшать кнопки в панели навигации используя тот же Appearance API.
Пока я погружался в кастомизацию кнопок, я открыл для себя метод UIImage появившийся в iOS 5, resizableImageWithCapInsets. Я решил отвлечься от первоначальной идеи издеваться над панелью навигации, чтобы понять, как работает установка фиксированных границ.
(Прим. переводчика — я не нашел перевода лучше, одолжите?)
Этот пост посвящен тому, что я изучил

Установка границ для UIButton


Как написано в документации, resizableImageWithCapInsets добавляет фиксированные границы к изображению, и когда оно резайзится или масштабируется, эти границы не изменяются. Лучше всего это можно понять из примера. Давайте представим, что я хочу, чтобы все кнопки в моем интерфейсе выглядели одинаково: градиент с белой границей. Ниже представлено изображение для примеров к этому посту (изображение на сером фоне, чтобы лучше выделить белую границу):

В зависимости от контекста использования, кнопка может появляться где угодно, и размер ее может изменяться. Обычно используется следующий код для создания кнопки с фоновым изображением:
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(80, 130, 160, 44)];  
[button setTitle:@"Test Button" forState:UIControlStateNormal];
// Картинка без фиксированных границ
UIImage *buttonImage = [UIImage imageNamed:@"blueButton"];
[button addTarget:self action:@selector(buttonPressed:) forControlEvents: UIControlEventTouchUpInside];        
[button setBackgroundImage:buttonImage forState:UIControlStateNormal];
[[self view] addSubview:button];


Как можно увидеть, кнопка растянута во всех направляниях. Теперь изменим код, включив фиксированные границы. Но прежде, давайте посмотрим сигнатуру данного метода:
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets

Заглянув чуть дальше, обнаружим, что UIEdgeInserts определяется как структура:
typedef struct {
   CGFloat top, left, bottom, right;
} UIEdgeInsets;


UIEdgeInsets — это структура, которая определяет float-значения для каждой фиксированной границы: верхняя, левая, нижняя и правая области изображения. Чтобы применить это к нашей кнопки, нужно сделать следующее:
// Изображение с установленными границами
UIImage *buttonImage = [[UIImage imageNamed:@"blueButton"]  
   resizableImageWithCapInsets:UIEdgeInsetsMake(0, 16, 0, 16)];

Это создаст изображение, в котором левые и правые 16 пикселей оригинального изображения не масштабируются и не ресайзятся при растягивании изображения до размера кнопки. Окончательный результат:


Cap Insets with UIBarButtonItem


Мы можем использовать то же самое изображение для кнопки в панели навигации. Без задания границ, кнопка выглядит вот так:

Код ниже демонстрирует создание кнопки с фиксированными 12 пикселями изображения по всей рамке:
UIImage *backButton = [[UIImage imageNamed:@"blueButton"]  
   resizableImageWithCapInsets:UIEdgeInsetsMake(12, 12, 12, 12)];

Окончательный результат:


Прим. переводчика — использование данной технологии аналогично использованию техники 9-patch в Android, за исключением того, что здесь не требуется заранее готовить изображение.
Tags:
Hubs:
+4
Comments 5
Comments Comments 5

Articles