Pull to refresh

Знакомство с СALayer

Reading time6 min
Views31K
Добро пожаловать! В данной статье вы познакомитесь с ключевой темой операционной системы iOS: которая называется «слои». Вы, скорее всего, уже знаете о View, но вы можете не знать то, что каждое view опирается на то, что называется слоем(layer). Слои являются частью Core Animation фреймворка.

Вы можете сказать, «Какой это имеет смысл? Я никогда ранее не использовал слои, поэтому это может и не быть столь важным.» Знаете ли вы это или нет, но ваше приложение интенсивно использует слои. В iOS каждое представление подтверждается слоем, независимо от того, какое оно. Слои существуют, таким образом, что iOS может легко получить растровую информацию о представлениях, с целью ее дальнейшей передачи для GPU (Устройства Обработки Графики). Посмотрите на изображение ниже, для визуального представления, где Core Animation находиться в иерархии iOS структуры.



Почему Слои? Немного теории.


На таких устройствах, как смартфоны, пользователи ожидают большую скорость во всем, что они делают. Очень важным является поддержка последовательной частоты кадров, которую пользователи воспринимают как «плавную работу». На iOS устройствах эта скорость составляет 60 кадров в секунду. Для того, чтобы сохранить системные перемещения на этой скорости был создан слой графической функциональности, которая работает непосредственно на GPU(устройство обработки графики): OpenGL.

OpenGL обеспечивает самый низкий уровень (и самый быстрый) доступ к графическим устройствам iOS. Тем не менее, существует компромисс: OpenGL очень примитивен, и даже самые простые задачи требуют написания очень большого количества кода.

Для решения данной проблемы, был создан Core Graphics, который обеспечивает несколько более высокий уровень функциональности с меньшим количеством кода. Для простоты работы с Core Graphics, был создан Core Animation. Он предоставляет класс CALayer, и позволяет получать некоторый базовый доступ низкого уровня к графическим возможностям.

После того, как компания Apple решила, что более продвинутая функциональность Core Animation не всегда необходима в обычных приложениях, был создан UIKit, который обеспечивает самый высокий уровень доступа к графике. Преимуществом данной схемы является то, что вы можете выбрать, какой уровень доступа к графике вам нужно в вашем приложении и выбирать требуемую функциональность, что может помочь в предотвращении написания ненужного кода.

Недостаток заключается в том, что более высокие уровни API предлагают меньше функциональных возможностей. Мораль этой истории заключается в следующем: CALayer существует, таким образом, что IOS может быстро и легко создавать растровую информацию об иерархии представлений вашего приложения, которая затем будет передана в Core Graphics, и в конечном итоге в OpenGL, и в последствии будет отображена на экране устройства посредством GPU. Несмотря на то, что нет необходимости использовать CALayer непосредственно в большинстве случаев, API — нижнего уровня предоставляет разработчикам некоторые более гибкие настройки, которые мы рассмотрим в этой статье.

Доступ к CALayer


Достаточно говорить о том, почему существуют слои. Давайте приступим к работе! Как я уже упоминал выше, каждое представление опирается на слой, к которому можно получить доступ через свойство layer для UIView. Предполагая, что у вас есть объект MyView, вы можете получить доступ к его слою следующим образом:

myView.layer

Хорошо, что мы можем сделать со слоем, как только мы получили к нему доступ? Вы будете удивлены, увидев огромное количество новых возможностей. В остальной части статьи я расскажу о некоторых из них.

Демо-проект


Во-первых, скачайте стартовый проект и давайте начнем! Лучший способ научиться что-то делать — это практика, так что мы в этом приложении будем добавлять пользовательские эффекты для слоев. Открыв проект, вы увидите, что это относительно простое приложение. Это пустое белое представление с черным квадратным View в центре. Давайте его немного приведем в порядок. Перейдите к ViewController.swift и приступим.



Создание закругленных углов


Вы можете использовать свойство cornerRadius из CALayer для закругления углов. Давайте попробуем это сделать. Внутри viewDidLoad (), добавьте следующую строку:

box.layer.cornerRadius = 5

Как и следовало ожидать, эта строка кода добавит угловой радиус 5 слою поля. Это выглядит следующим образом:



Не так уж плохо, верно? Увеличение радиуса угла делает края более закругленными, а уменьшение радиуса угла делает края менее закругленными. По умолчанию, все слои имеют радиус скругления углов равный 0.



Добавление эффекта теней


Тень помогает создавать ощущение глубины нашего приложения, и является очень полезной при проектировании интерфейсов. Используя теневой эффект, мы можем создать «плавный» эффект представления на экране устройства. Давайте посмотрим, как создать эффект тени, используя CALayer. Вставьте следующий код в методе viewDidLoad в ViewController:

box.layer.shadowOffset = CGSizeMake(5, 5)  // 1
box.layer.shadowOpacity = 0.7 // 2
box.layer.shadowRadius = 5 // 3
box.layer.shadowColor = UIColor(red: 44.0/255.0, green: 62.0/255.0, blue: 80.0/255.0, alpha: 1.0).CGColor // 4

Строка 1: Устанавливает смещение тени слоя до (5, 5). Устанавливая (5, 5) в качестве значения layer.shadowOffset означает, что тень слоя должна быть смещена на 5 единиц вправо и на 5 единиц ниже box.layer.

Строка 2: Эта строка устанавливает непрозрачность тени слоя до 0,7. Это означает, что тень не должна превышать непрозрачность более, чем на 70%.

Строка 3: Эта строка устанавливает радиус тени слоя до 5. Радиусом тени является радиус размытия, для применения его к тени, создаваемой посредством box.layer. Более высокий радиус делает тень более размытой, но менее заметной. Меньший радиус делает тень более видимой, и более сфокусированной. Радиус тени 0 приводит к полному размытию. Другими словами, посредством вышеприведенных операций можно точно установить форму и размер слоя.

Строка 4: Эта строка устанавливает цвет тени слоя в темно серый. Обратите внимание, что это свойство имеет тип CGColor, а не UIColor. Преобразовывать эти два типа очень легко. Вы просто пишите myUIColor.CGColor.

Давайте взглянем что у нас получилось!



Использование границ


CALayer также позволяет легко применять границы. Давайте добавим к полю границу.

box.layer.borderColor = UIColor.blueColor().CGColor // 1
box.layer.borderWidth = 3 // 2

Строка 1: Эта строка устанавливает цвет границы поля до темно синего. Это приведет к установке темно синего цвета для любой границы отображаемого поля.

Строка 2: Эта строка устанавливает ширину границы поля до 3. Это означает, что граница, вычерченная вокруг поля, будет иметь толщину 3 единицы.

Давайте посмотрим как будет выглядеть поле с границей.



Отображение изображения


Кроме того, можно назначить изображение слоем, таким способом слой отображает изображение. У нас есть прекрасная картинка дерева, в нашем проекте, благодаря этому сайту. Давайте заставим наш слой отображать изображение. Вставьте следующий код в viewDidLoad:

box.layer.contents = UIImage(named: "Tree.jpg")?.CGImage // 1
box.layer.contentsGravity = kCAGravityResize // 2
box.layer.masksToBounds = true // 3

Строка 1: Она создает новый UIImage с именем файла tree.jpg и присваивает его свойству слоя contents.

Строка 2: Она устанавливает размер содержимого слоя, чтобы изменить его размер, что означает, что все содержимое слоя будет изменено, чтобы соответствовать размерам слоя.

Строка 3: Мы изменяем masksToBounds в состояние true, так что любые подслои слоя, которые выходят за его пределы будут обрезаны к этим границам. Если вы не понимаете, что это значит, вы можете установить его в состояние false, чтобы увидеть различия.

Вот результат.



Цвет фона и непрозрачность


Мы говорили о добавлении специальных эффектов CALayer, которые не представляются возможными посредством использования UIKit, но мы должны также обсудить, как можно изменить большинство свойств UIKit влияющих на UIView посредством CALayer. В качестве примера, вы можете изменить цвет фона и прозрачность представления, подобно следующему:

box.layer.backgroundColor = UIColor.blueColor().CGColor
box.layer.opacity = 0.5

Характеристики CALayer


Добавление большого количества пользовательских эффектов для слоев может оказать влияние на его характеристики. Теперь мы будем говорить о двух свойствах CALayer, которые могут помочь нам значительно улучшить производительность приложения.

Во-первых, давайте поговорим о drawsAsynchronously. Это свойство CALayer определяет, требуется ли процессору(ЦПУ) выполнять отображение слоя в фоновом потоке. Если установлено значение true, то слой будет выглядеть точно так же, как обычно, но потребуется вычисление ЦПУ чтобы отобразить это вычисление в фоновом потоке. Вы должны установить значение true, если у вас имеется представление, которое необходимо часто перерисовывать, например, карта или таблица.

Далее рассмотрим shouldRasterize. Это свойство CALayer которое определяет, должен ли слой быть растрирован. Когда это свойство имеет значение true, то слой рисуется один раз. Всякий раз при его анимировании, он не будет перерисовываться и растровая информация будет удаляться. Данному свойству должно быть присвоено значение true, если у вас есть представление, которое не нужно часто перерисовывать. Обратите внимание, что при установке shouldRasterize, отображение слоя на устройствах Retina может измениться. Это происходит потому, что слои имеют так называемый масштаб растрирования, при помощи которого происходит растрирование слоя. Чтобы не допустить это, установите rasterizationScale на UIScreen.mainScreen().scale, так чтобы слой растрировался в таком же масштабе, что и отображается экран.

Следует отметить, что на 99%, вы не должны использовать любое из этих свойств самостоятельно. Установка их вручную может привести к снижению производительности. Установите только одно из этих 2-ух свойств по своему усмотрению, если вы определили, что изображение или слой влияет на производительность приложения.

Подведем итоги


Теперь вы знаете, что такое CALayer! Имея некоторые знания низкоуровневой графики, вы можете создавать некоторые интересные эффекты. Надеюсь, для новичков статья будет полезной.

Для справки, вы можете скачать готовый проект. Если у вас есть какие-либо вопросы или пожелания, пожалуйста, оставьте мне комментарий ниже.
Tags:
Hubs:
+14
Comments0

Articles

Change theme settings