Поиск…
Создание CALayer
Вы можете создать CALayer и установить его фрейм следующим образом:
Swift:
let layer = CALayer()
layer.frame = CGRect(x: 0, y: 0, width: 60, height: 80)
Objective-C:
CALayer *layer = [[CALayer alloc] init];
layer.frame = CGRectMake(0, 0, 60, 80);
Затем вы можете добавить его в качестве подуровня для существующего CALayer:
Swift:
existingLayer.addSublayer(layer)
Objective-C:
[existingLayer addSublayer:layer];
Замечания:
Для этого вам необходимо включить структуру QuartzCore.
Swift:
@import QuartzCore
Objective-C
#import <QuartzCore/QuartzCore.h>
Создание частиц с помощью CAEmitterLayer
Класс CAEmitterLayer предоставляет систему эмиттеров частиц для Core Animation. Частицы определяются экземплярами CAEmitterCell .
Частицы рисуются над цветом фона и границей слоя.
var emitter = CAEmitterLayer()
emitter.emitterPosition = CGPoint(x: frame.size.width / 2.0, y: -20)
emitter.emitterShape = kCAEmitterLayerLine
emitter.emitterSize = CGSize(width: frame.size.width, height: 1)
emitter.emitterCells = cells
layer.addSublayer(emitter)
Просмотр эмиттера с пользовательским изображением
Например, мы создадим представление, которое содержит слой эмиттера и анимирует частицы.
import QuartzCore
class ConfettiView: UIView {
// main emitter layer
var emitter: CAEmitterLayer!
// array of color to emit
var colors: [UIColor]!
// intensity of appearance
var intensity: Float!
private var active :Bool!
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
setup()
}
override init(frame: CGRect) {
super.init(frame: frame)
setup()
}
func setup() {
// initialization
colors = [UIColor.redColor(),
UIColor.greenColor(),
UIColor.blueColor()
]
intensity = 0.2
active = false
}
func startConfetti() {
emitter = CAEmitterLayer()
emitter.emitterPosition = CGPoint(x: frame.size.width / 2.0, y: -20)
emitter.emitterShape = kCAEmitterLayerLine
emitter.emitterSize = CGSize(width: frame.size.width, height: 1)
var cells = [CAEmitterCell]()
for color in colors {
cells.append(confettiWithColor(color))
}
emitter.emitterCells = cells
layer.addSublayer(emitter)
active = true
}
func stopConfetti() {
emitter?.birthRate = 0
active = false
}
func confettiWithColor(color: UIColor) -> CAEmitterCell {
let confetti = CAEmitterCell()
confetti.birthRate = 10.0 * intensity
confetti.lifetime = 180.0 * intensity
confetti.lifetimeRange = 0
confetti.color = color.CGColor
confetti.velocity = CGFloat(350.0 * intensity)
confetti.velocityRange = CGFloat(40.0 * intensity)
confetti.emissionLongitude = CGFloat(M_PI)
confetti.emissionRange = CGFloat(M_PI_4)
confetti.spin = CGFloat(3.5 * intensity)
confetti.spinRange = CGFloat(4.0 * intensity)
// WARNING: A layer can set this property to a CGImageRef to display the image as its contents.
confetti.contents = UIImage(named: "confetti")?.CGImage
return confetti
}
internal func isActive() -> Bool {
return self.active
}
}
Вам нужно добавить изображение «confetti» или указать rect с confetti.contentsRect
Как добавить UIImage в CALayer
Вы можете добавить изображение на layer
вида, просто используя его свойство contents
:
myView.layer.contents = UIImage(named: "star")?.CGImage
- Обратите внимание, что
UIImage
необходимо преобразовать вCGImage
.
Если вы хотите добавить изображение в свой собственный слой, вы можете сделать это следующим образом:
let myLayer = CALayer()
let myImage = UIImage(named: "star")?.CGImage
myLayer.frame = myView.bounds
myLayer.contents = myImage
myView.layer.addSublayer(myLayer)
Изменение внешнего вида
Вышеприведенный код создает такое же представление. Светло-голубой - UIView
а синяя звезда - UIImage
.
Однако, как вы видите, он выглядит неровным. Это связано с тем, что UIImage
меньше, чем UIView
поэтому он масштабируется, чтобы заполнить представление, которое по умолчанию не указано ничем другим.
Приведенные ниже примеры показывают вариации на слой contentsGravity
собственности. Код выглядит так:
myView.layer.contents = UIImage(named: "star")?.CGImage
myView.layer.contentsGravity = kCAGravityTop
myView.layer.geometryFlipped = true
В iOS вы можете установить свойство geometryFlipped
в значение true
если вы делаете что-либо с верхней или нижней гравитацией, иначе это будет противоположно тому, что вы ожидаете. (Только гравитация переворачивается вертикально, а не рендеринг содержимого. Если у вас возникли проблемы с переворачиванием содержимого, см. Этот ответ переполнения стека ).
Есть два UIView
ниже примеры для каждого contentsGravity
настройки, один вид больше , чем UIImage
, а другой меньше. Таким образом, вы можете увидеть эффекты масштабирования и гравитации.
kCAGravityResize
Это значение по умолчанию.
kCAGravityResizeAspect
kCAGravityResizeAspectFill
kCAGravityCenter
kCAGravityTop
kCAGravityBottom
kCAGravityLeft
kCAGravityRight
kCAGravityTopLeft
kCAGravityTopRight
kCAGravityBottomLeft
kCAGravityBottomRight
связанные с
- Свойство режима содержимого вида
- Рисование
UIImage
вdrawRect
с помощьюCGContextDrawImage
- CALayer Tutorial: Начало работы
Заметки
- Этот пример исходит из этого ответа на переполнение стека .
Добавление преобразований в CALayer (перевод, поворот, масштабирование)
основы
Существует несколько различных преобразований, которые вы можете сделать на слое, но основные из них
- переводить (перемещать)
- масштаб
- вращаться
Чтобы сделать преобразования на CALayer
, вы устанавливаете свойство transform
слоя в тип CATransform3D
. Например, чтобы перевести слой, вы сделали бы что-то вроде этого:
myLayer.transform = CATransform3DMakeTranslation(20, 30, 0)
Слово Make
используется в имени для создания исходного преобразования: CATransform3D Make Translation. Последующие преобразования, которые применяются, опускают Make
. См., Например, эту ротацию, за которой следует перевод:
let rotation = CATransform3DMakeRotation(CGFloat(30.0 * M_PI / 180.0), 20, 20, 0)
myLayer.transform = CATransform3DTranslate(rotation, 20, 30, 0)
Теперь, когда у нас есть основа, как сделать преобразование, давайте посмотрим на некоторые примеры того, как делать каждый. Во-первых, я покажу, как я создаю проект, если вы хотите поиграть с ним.
Настроить
В следующих примерах я создал приложение Single View и добавил UIView
с голубым фоном в раскадровку. Я подключил представление к контроллеру вида с помощью следующего кода:
import UIKit
class ViewController: UIViewController {
var myLayer = CATextLayer()
@IBOutlet weak var myView: UIView!
override func viewDidLoad() {
super.viewDidLoad()
// setup the sublayer
addSubLayer()
// do the transform
transformExample()
}
func addSubLayer() {
myLayer.frame = CGRect(x: 0, y: 0, width: 100, height: 40)
myLayer.backgroundColor = UIColor.blueColor().CGColor
myLayer.string = "Hello"
myView.layer.addSublayer(myLayer)
}
//******** Replace this function with the examples below ********
func transformExample() {
// add transform code here ...
}
}
Существует много разных типов CALayer
, но я решил использовать CATextLayer
чтобы преобразования были более четкими визуально.
Переведите
Преобразование трансляции перемещает слой. Основной синтаксис
CATransform3DMakeTranslation(tx: CGFloat, ty: CGFloat, tz: CGFloat)
где tx
- изменение координат x, ty
- изменение y, а tz
- изменение z.
пример
В iOS начало координат находится в левом верхнем углу, поэтому, если мы хотим переместить слой 90 точек вправо и 50 точек вниз, мы сделаем следующее:
myLayer.transform = CATransform3DMakeTranslation(90, 50, 0)
Заметки
- Помните, что вы можете вставить это в метод
transformExample()
в код проекта выше. - Поскольку мы просто будем иметь дело с двумя измерениями здесь,
tz
устанавливается в0
. - Красная линия на изображении выше идет от центра исходного местоположения к центру нового места. Это потому, что преобразования выполняются по отношению к опорной точке и точка привязки по умолчанию находится в центре слоя.
Масштаб
Масштабное преобразование растягивает или скручивает слой. Основной синтаксис
CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat)
где sx
, sy
и sz
- числа, с помощью которых можно масштабировать (умножать) координаты x, y и z соответственно.
пример
Если бы мы хотели половину ширины и утроить высоту, мы сделали бы следующее
myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)
Заметки
- Поскольку мы работаем только в двух измерениях, мы просто умножаем координаты z на 1.0, чтобы они не были затронуты.
- Красная точка на изображении выше представляет собой опорную точку. Обратите внимание на то, как масштабирование делается по отношению к точке привязки. То есть, все, либо растянуто в стороне или от точки привязки.
Поворот
Преобразование поворота поворачивает слой вокруг опорной точки (центр слоя по умолчанию). Основной синтаксис
CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat)
где angle
- это угол в радианах, чтобы слой был повернут, а x
, y
и z
- оси, вокруг которых можно вращать. Установка оси на 0 отменяет поворот вокруг этой конкретной оси.
пример
Если бы мы хотели повернуть слой по часовой стрелке на 30 градусов, мы сделали бы следующее:
let degrees = 30.0
let radians = CGFloat(degrees * M_PI / 180)
myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)
Заметки
- Поскольку мы работаем в двух измерениях, мы хотим, чтобы плоскость xy вращалась вокруг оси z. Таким образом, мы устанавливаем
x
иy
0.0
и устанавливаемz
в1.0
. - Это повернуло слой по часовой стрелке. Мы могли бы вращаться против часовой стрелки, установив
z
на-1.0
. - Красная точка показывает, где находится опорная точка. Вращение осуществляется вокруг точки привязки.
Несколько преобразований
Чтобы объединить несколько преобразований, мы могли бы использовать
CATransform3DConcat(a: CATransform3D, b: CATransform3D)
Однако мы будем делать одно за другим. Первое преобразование будет использовать Make
в своем имени. Следующие преобразования не будут использовать Make
, но они будут принимать предыдущее преобразование в качестве параметра.
пример
На этот раз мы объединим все три предыдущих преобразования.
let degrees = 30.0
let radians = CGFloat(degrees * M_PI / 180)
// translate
var transform = CATransform3DMakeTranslation(90, 50, 0)
// rotate
transform = CATransform3DRotate(transform, radians, 0.0, 0.0, 1.0)
// scale
transform = CATransform3DScale(transform, 0.5, 3.0, 1.0)
// apply the transforms
myLayer.transform = transform
Заметки
- Порядок выполнения преобразований в вопросах.
- Все было сделано по отношению к опорной точке (красная точка).
Примечание о якорной точке и позиции
Мы выполнили все наши преобразования выше, не меняя опорную точку. Иногда это необходимо изменить, хотя, например, если вы хотите повернуть вокруг какой-то другой точки, кроме центра. Однако это может быть немного сложно.
Якорная точка и позиция находятся на одном и том же месте. Якорная точка выражается как единица системы координат слоя (по умолчанию 0.5, 0.5
), и позиция выражается в системе координат суперслоя. Они могут быть установлены следующим образом:
myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
myLayer.position = CGPoint(x: 50, y: 50)
Если вы устанавливаете точку привязки без изменения положения, тогда рамка изменяется так, что позиция будет в нужном месте. Или, точнее, рама пересчитываются на основе новой опорной точки и старой позиции. Это обычно дает неожиданные результаты. Следующие две статьи прекрасно обсуждают это.
Смотрите также
Этот пример изначально исходит из этого примера переполнения стека .
Отключить анимацию
CALayer
свойства свойств CALayer
. Если это нежелательно, их можно отключить следующим образом.
стриж
CATransaction.begin()
CATransaction.setDisableActions(true)
// change layer properties that you don't want to animate
CATransaction.commit()
Objective-C
[CATransaction begin];
[CATransaction setDisableActions:YES];
// change layer properties that you don't want to animate
[CATransaction commit];
Закругленные углы
layer.masksToBounds = true;
layer.cornerRadius = 8;
Тени
Вы можете использовать 5 свойств на каждом уровне для настройки теней:
-
shadowOffset
- это свойство перемещает вашу тень влево / вправо или вверх / вниз
self.layer.shadowOffset = CGSizeMake(-1, -1); // 1px left and up
self.layer.shadowOffset = CGSizeMake(1, 1); // 1px down and right
-
shadowColor
- устанавливает цвет вашей тени
self.layer.shadowColor = [UIColor blackColor].CGColor;
-
shadowOpacity
- это непрозрачность тени, от0
до1
self.layer.shadowOpacity = 0.2;
-
shadowRadius
- это радиус размытия (эквивалент свойства размытия в Sketch или Photoshop)
self.layer.shadowRadius = 6;
-
shadowPath
- это важное свойство производительности, когда unset iOS основывает тень на альфа-канале представления, который может быть интенсивным с использованием сложного PNG с альфой. Это свойство позволяет вам форсировать форму для вашей тени и быть более совершенным из-за этого.
Objective-C
self.layer.shadowPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0,100,100)]; //this does a circular shadow
Swift 3
self.layer.shadowPath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 100, height: 100)).cgPath