Buscar..


Creando un CALayer

Puedes crear un CALayer y establecer su marco de esta manera:

Rápido:

let layer = CALayer()
layer.frame = CGRect(x: 0, y: 0, width: 60, height: 80)

C objetivo:

CALayer *layer = [[CALayer alloc] init];
layer.frame = CGRectMake(0, 0, 60, 80);

Luego puede agregarlo como una subcapa a un CALayer existente:

Rápido:

existingLayer.addSublayer(layer)

C objetivo:

[existingLayer addSublayer:layer];

Nota:

Para hacer esto necesitas incluir el framework QuartzCore.

Rápido:

 @import QuartzCore

C objetivo

#import <QuartzCore/QuartzCore.h>

Creando partículas con CAEmitterLayer

La clase CAEmitterLayer proporciona un sistema de emisor de partículas para Core Animation. Las partículas están definidas por instancias de CAEmitterCell .

Las partículas se dibujan sobre el color de fondo y el borde de la capa.

        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)

Vista del emisor con imagen personalizada.

Por ejemplo, crearemos una vista que contenga una capa emisora ​​y anime las partículas.

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
    }
}

Debe agregar una imagen de "confeti" o definir rect con confetti.contentsRect

Cómo agregar un UIImage a un CALayer

Puede agregar una imagen a la layer una vista simplemente usando su propiedad de contents :

myView.layer.contents = UIImage(named: "star")?.CGImage
  • Tenga en cuenta que el UIImage necesita ser convertido a CGImage .

Si desea agregar la imagen en su propia capa, puede hacerlo de la siguiente manera:

let myLayer = CALayer()
let myImage = UIImage(named: "star")?.CGImage
myLayer.frame = myView.bounds
myLayer.contents = myImage
myView.layer.addSublayer(myLayer)

Modificando la apariencia

El código anterior produce una vista como esta. El azul claro es el UIView y la estrella azul oscuro es el UIImage .

imagen de la estrella en un calder

Como puedes ver, sin embargo, parece pixelado. Esto se debe a que el UIImage es más pequeño que el UIView por lo que se está escalando para completar la vista, que es el valor predeterminado, no se especifica nada más.

Los siguientes ejemplos muestran variaciones en la propiedad contentsGravity la capa. El código se ve así:

myView.layer.contents = UIImage(named: "star")?.CGImage
myView.layer.contentsGravity = kCAGravityTop
myView.layer.geometryFlipped = true

En iOS, es posible que desee establecer la propiedad geometryFlipped en true si está haciendo algo con gravedad superior o inferior, de lo contrario será lo contrario de lo que espera. (Solo la gravedad se invierte verticalmente, no la representación del contenido. Si tiene problemas con el contenido que se invierte, consulte esta respuesta de Desbordamiento de pila ).

Hay dos ejemplos de UIView continuación para cada configuración de contentsGravity UIView , una vista es más grande que el UIImage y la otra es más pequeña. De esta manera puedes ver los efectos de la escala y la gravedad.

kCAGravityResize

Este es el valor predeterminado.

kCAGravityResize

kCAGravityResizeAspect

kCAGravityResizeAspect

kCAGravityResizeAspectFill

kCAGravityResizeAspectFill

kCAGravityCenter

kCAGravityCenter

kCAGravityTop

kCAGravityTop

kCAGravityBottom

kCAGravityBottom

kCAGravityLeft

kCAGravityLeft

kCAGravityRight

kCAGravityRight

kCAGravityTopLeft

kCAGravityTopLeft

kCAGravityTopRight

kCAGravityTopRight

kCAGravityBottomLeft

kCAGravityBottomLeft

kCAGravityBottomRight

kCAGravityBottomRight

Relacionado

Notas

Agregar transformaciones a un CALayer (traducir, rotar, escalar)

Lo esencial

Hay una serie de transformaciones diferentes que puedes hacer en una capa, pero las básicas son

  • traducir
  • escala
  • girar

transformaciones básicas

Para realizar transformaciones en un CALayer , establezca la propiedad de transform la capa en un tipo CATransform3D . Por ejemplo, para traducir una capa, harías algo como esto:

myLayer.transform = CATransform3DMakeTranslation(20, 30, 0)

La palabra Make se usa en el nombre para crear la transformación inicial: CATransform3D Make Translation. Las transformaciones subsiguientes que se aplican omiten la Make . Vea, por ejemplo, esta rotación seguida de una traducción:

let rotation = CATransform3DMakeRotation(CGFloat(30.0 * M_PI / 180.0), 20, 20, 0)
myLayer.transform = CATransform3DTranslate(rotation, 20, 30, 0)

Ahora que tenemos la base de cómo hacer una transformación, veamos algunos ejemplos de cómo hacer cada uno. Primero, sin embargo, mostraré cómo configuro el proyecto en caso de que también quieras jugar con él.

Preparar

Para los siguientes ejemplos, configuro una aplicación de vista única y agregué una vista UIView con un fondo azul claro al guión gráfico. Conecté la vista al controlador de vista con el siguiente código:

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 ...
        
        
    }

} 

Hay muchos tipos diferentes de CALayer , pero elegí usar CATextLayer para que las transformaciones sean más claras visualmente.

Traducir

La transformación de la traducción mueve la capa. La sintaxis básica es

CATransform3DMakeTranslation(tx: CGFloat, ty: CGFloat, tz: CGFloat)

donde tx es el cambio en las coordenadas x, ty es el cambio en y, y tz es el cambio en z.

Ejemplo

traducir ejemplo

En iOS, el origen del sistema de coordenadas está en la parte superior izquierda, por lo que si quisiéramos mover la capa 90 puntos a la derecha y 50 puntos hacia abajo, haríamos lo siguiente:

myLayer.transform = CATransform3DMakeTranslation(90, 50, 0)

Notas

  • Recuerde que puede pegar esto en el método transformExample() en el código del proyecto anterior.
  • Ya que vamos a tratar dos dimensiones aquí, tz se establece en 0 .
  • La línea roja en la imagen de arriba va desde el centro de la ubicación original hasta el centro de la nueva ubicación. Esto se debe a que las transformaciones se realizan en relación con el punto de anclaje y el punto de anclaje por defecto está en el centro de la capa.

Escala

La transformación a escala estira o aplasta la capa. La sintaxis básica es

CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat)

donde sx , sy y sz son los números por los cuales escalar (multiplicar) las coordenadas x, y y z, respectivamente.

Ejemplo

ejemplo de escala

Si quisiéramos la mitad del ancho y el triple de la altura, haríamos lo siguiente

myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)

Notas

  • Como solo trabajamos en dos dimensiones, solo multiplicamos las coordenadas z por 1.0 para no afectarlas.
  • El punto rojo en la imagen de arriba representa el punto de anclaje. Observe cómo se realiza el escalado en relación con el punto de anclaje. Es decir, todo se estira hacia o desde el punto de anclaje.

Girar

La transformación de rotación gira la capa alrededor del punto de anclaje (el centro de la capa de forma predeterminada). La sintaxis básica es

CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat)

donde angle es el ángulo en radianes en que se debe rotar la capa y x , y y z son los ejes sobre los cuales rotar. Establecer un eje en 0 cancela una rotación alrededor de ese eje en particular.

Ejemplo

rotar ejemplo

Si quisiéramos rotar una capa en sentido horario 30 grados, haríamos lo siguiente:

let degrees = 30.0
let radians = CGFloat(degrees * M_PI / 180)
myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)

Notas

  • Como estamos trabajando en dos dimensiones, solo queremos que el plano xy gire alrededor del eje z. Así establecimos x e y a 0.0 y establecimos z a 1.0 .
  • Esto hizo girar la capa en el sentido de las agujas del reloj. Podríamos haber girado en sentido contrario a las manecillas del reloj estableciendo z en -1.0 .
  • El punto rojo muestra dónde está el punto de anclaje. La rotación se realiza alrededor del punto de anclaje.

Transformaciones multiples

Para combinar múltiples transformaciones podríamos usar concatinación como esta

CATransform3DConcat(a: CATransform3D, b: CATransform3D)

Sin embargo, vamos a hacer uno tras otro. La primera transformación utilizará la Make en su nombre. Las siguientes transformaciones no utilizarán Make , pero tomarán la transformación anterior como un parámetro.

Ejemplo

ejemplo de múltiples transformaciones

Esta vez combinamos las tres transformaciones anteriores.

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

Notas

  • El orden en que se realizan las transformaciones en materia.
  • Todo se hizo en relación con el punto de anclaje (punto rojo).

Una nota sobre el punto de anclaje y la posición

Hicimos todas nuestras transformaciones anteriores sin cambiar el punto de anclaje. Sin embargo, a veces es necesario cambiarlo, como si desea girar alrededor de algún otro punto además del centro. Sin embargo, esto puede ser un poco complicado.

El punto de anclaje y la posición están en el mismo lugar. El punto de anclaje se expresa como una unidad del sistema de coordenadas de la capa (el valor predeterminado es 0.5, 0.5 ) y la posición se expresa en el sistema de coordenadas de la superapa. Se pueden configurar de esta manera

myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
myLayer.position = CGPoint(x: 50, y: 50)

Si solo establece el punto de anclaje sin cambiar la posición, entonces el marco cambia para que la posición esté en el lugar correcto. O más precisamente, el marco se recalcula basándose en el nuevo punto de anclaje y la posición anterior. Esto suele dar resultados inesperados. Los siguientes dos artículos tienen una excelente discusión de esto.

Ver también

Este ejemplo proviene originalmente de este ejemplo de desbordamiento de pila .

Deshabilitar animaciones

CALayer animaciones de propiedades de CALayer están habilitadas por defecto. Cuando esto no es deseable, se pueden desactivar de la siguiente manera.

Rápido

CATransaction.begin()
CATransaction.setDisableActions(true)

// change layer properties that you don't want to animate

CATransaction.commit()

C objetivo

[CATransaction begin];
[CATransaction setDisableActions:YES];

// change layer properties that you don't want to animate

[CATransaction commit];

Esquinas redondeadas

layer.masksToBounds = true;
layer.cornerRadius = 8;

Oscuridad

Puedes usar 5 propiedades en cada capa para configurar tus sombras:

  • shadowOffset - esta propiedad mueve tu sombra a la izquierda / derecha o arriba / abajo
self.layer.shadowOffset = CGSizeMake(-1, -1); // 1px left and up

self.layer.shadowOffset = CGSizeMake(1, 1); // 1px down and right
  • shadowColor - esto establece el color de tu sombra
self.layer.shadowColor = [UIColor blackColor].CGColor;
  • shadowOpacity - esta es la opacidad de la sombra, de 0 a 1
self.layer.shadowOpacity = 0.2;
  • shadowRadius : este es el radio de desenfoque (equivalente a la propiedad de desenfoque en Sketch o Photoshop)
self.layer.shadowRadius = 6;
  • shadowPath : esta es una propiedad importante para el rendimiento, cuando el iOS no configurado basa la sombra en el canal alfa de la vista, que puede ser intensivo en el rendimiento con un PNG complejo con alfa. Esta propiedad te permite forzar una forma para tu sombra y tener más rendimiento gracias a ella.

C objetivo

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
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow