Поиск…


Создание 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 .

звездное изображение на CALayer

Однако, как вы видите, он выглядит неровным. Это связано с тем, что 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

Это значение по умолчанию.

kCAGravityResize

kCAGravityResizeAspect

kCAGravityResizeAspect

kCAGravityResizeAspectFill

kCAGravityResizeAspectFill

kCAGravityCenter

kCAGravityCenter

kCAGravityTop

kCAGravityTop

kCAGravityBottom

kCAGravityBottom

kCAGravityLeft

kCAGravityLeft

kCAGravityRight

kCAGravityRight

kCAGravityTopLeft

kCAGravityTopLeft

kCAGravityTopRight

kCAGravityTopRight

kCAGravityBottomLeft

kCAGravityBottomLeft

kCAGravityBottomRight

kCAGravityBottomRight

связанные с

Заметки

Добавление преобразований в 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


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow