Pull to refresh

Красивые фоновые текстуры в iOS

Reading time 3 min
Views 8.1K
Друзья.
Сегодня речь пойдёт о создании красивых бэкграундов в iOs приложениях с точки зрения программиста, расчёте их разрешений, специфики разных Apple устройств и обходе подводных камней. Многое из этого для большинства iOs разработчиков покажется очевидным, но я буду рад, если для некоторых это станет инструкцией при непосредственной работе.

Итак, мы должны ответить на следующие вопросы:
  1. Какие разрешения выбирать для картинок.
  2. Как именовать картинки.
  3. Как это использовать.


Какие разрешения выбирать для картинок


Не важно, для iPad, iPhone, iPod или универсальное приложение мы пишем, будут поддерживаться обе ориентации устройства или только одна, в любом случае, нам бы хотелось, чтобы задумка дизайнера с фоном была правильно реализована точно как на картинке-прототипе. Для этого нам, в первую очередь, необходимо избежать масштабирования изображения, к тому же это также благоприятно повлияет на performance, что тоже неплохо. Поэтому нам нужно рассчитать точные размеры рабочей области окна (размер бэкграундной картинки).

Исходные данные
Разрешения iOs устройств:
  • iPhone 320x480
  • iPhone (Retina) 640x960
  • iPhone 5 (Retina) 640x1136
  • iPad 768x1024
  • iPad (Retina) 1536x2048


Высоты элементов:

  • Status Bar 20pt (20px без Retina и 40px с Retina)
  • Navigation Bar 44pt (44px без Retina и 88px с Retina)
  • Tab Bar 49pt (49px без Retina и 98px с Retina)


Теперь просто вычитаем из высоты экрана количество точек, что «съедают» элементы управления и получаем размеры картинок для бэкграунда, учитываем обе ориентации, если необходимо.

Например, если у нас присутствуют status bar и navigation bar, но нет tab bar, мы получаем:

Портретная ориентация:

  • iPhone 320x416
  • iPhone (Retina) 640x832
  • iPhone 5 (Retina) 640x1008
  • iPad 768x960
  • iPad (Retina) 1536x1920

Альбомная ориентация:
  • iPhone 480x256
  • iPhone (Retina) 960x512
  • iPhone 5 (Retina) 1136x512
  • iPad 1024x704
  • iPad (Retina) 2048x1408


Как именовать картинки


Согласно документации Apple среда сама выберет картинку нужного разрешения (для Retina или без) для нужного устройства, если в ресурсах присутствуют файлы с соответствующими суффиксами. Для Retina экранов это "@2x", для iPhone — "~iphone", для iPad — "~ipad". Внимание! Суффиксы чувствительны к регистру.

Кроме того, нам нужно учесть так же в названиях обе ориентации (предлагаю это сделать без суффикса для портретной и с помощью суффикса «l» для альбомной) и увеличенный размер картинки для iPhone 5 (многие это делают с помощью суффикса "-568h"). Эти суффиксы не обрабатываются системой автоматически и нам придётся делать это вручную.

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

  • iPhone background~iphone.png
  • iPhone (Retina) background@2x~iphone.png
  • iPhone 5 (Retina) background-568h@2x~iphone.png
  • iPad background~ipad.png
  • iPad (Retina) background@2x~ipad.png

Альбомная ориентация:
  • iPhone backgroundl~iphone.png
  • iPhone (Retina) backgroundl@2x~iphone.png
  • iPhone 5 (Retina) backgroundl-568h@2x~iphone.png
  • iPad backgroundl~ipad.png
  • iPad (Retina) backgroundl@2x~ipad.png


Как это использовать


Итак, картинки нужных разрешений созданы, теперь давайте заставим их работать так, как нужно.
Для начала сделаем функцию loadBgImage, которая будет выбирать нужную текстуру. Напоминаю, что нам вручную нужно подставлять только 2 суффикса к названию.

- (UIImage *) loadBgImageWithLandscapeOrientation: (BOOL) isLandscape
{
    static BOOL isIphone5 = [UIScreen mainScreen].bounds.size.height == 568;
    NSString * imageName = @"background";
    if (isLandscape)
    {
        imageName = [imageName stringByAppendingString: @"l"];
    }
    if (isIphone5)
    {
        imageName = [imageName stringByAppendingString: @"-568h"];
    }
    return [UIImage imageNamed: imageName];
}


А теперь добавим в наш view controller следующую функцию:

-(void)willAnimateRotationToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation duration:(NSTimeInterval)duration
{
    [super willAnimateRotationToInterfaceOrientation: toInterfaceOrientation duration: duration];
    [UIView beginAnimations:nil context:NULL];
    [UIView setAnimationDuration:duration];
    self.tableView.backgroundView =  [[UIImageView alloc] initWithImage: [self loadBgImageWithLandscapeOrientation: UIInterfaceOrientationIsLandscape(toInterfaceOrientation)]];
    [UIView commitAnimations];
}


Добавим аналогичный код первоначальной загрузки картинки в viewDidLoad и всё!

Обратите внимание, что мы меняем бэкграунд при смене ориентации, используя Core Animation, поэтому всё должно быть не только быстро, но и красиво. Кроме того, чтобы это работало ещё быстрее, советую растеризовать объекты, находящиеся на этом фоне, установив у них свойство view.layer.shouldRasterize в YES и указав в свойстве view.layer.rasterizationScale необходимый коэффициент маштабирования [UIScreen mainScreen].scale.

Всё, мы справились с заданием, которое ставили себе в самом начале.

Спасибо за внимание.
Tags:
Hubs:
-3
Comments 11
Comments Comments 11

Articles