Недавно я начал писать небольшой пример, чтобы лучше изучить 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:<hh user=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, за исключением того, что здесь не требуется заранее готовить изображение.
Автор: Dreddik