UIImage и resizableImageWithCapInsets

в 4:33, , рубрики: Appearance API, ios 5, resizableImageWithCapInsets, UIImage, масштабирование, разработка под iOS

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

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

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

- (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 пикселей оригинального изображения не масштабируются и не ресайзятся при растягивании изображения до размера кнопки. Окончательный результат:
UIImage и resizableImageWithCapInsets

Cap Insets with UIBarButtonItem

Мы можем использовать то же самое изображение для кнопки в панели навигации. Без задания границ, кнопка выглядит вот так:
UIImage и resizableImageWithCapInsets
Код ниже демонстрирует создание кнопки с фиксированными 12 пикселями изображения по всей рамке:

UIImage *backButton = [[UIImage imageNamed:@"blueButton"]  
   resizableImageWithCapInsets:UIEdgeInsetsMake(12, 12, 12, 12)];

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

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

Автор: Dreddik


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


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