Ricerca…


Creazione di un CALayer

Puoi creare un CALayer e impostarne la cornice in questo modo:

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);

È quindi possibile aggiungerlo come sottolivello a un CALayer esistente:

Swift:

existingLayer.addSublayer(layer)

Objective-C:

[existingLayer addSublayer:layer];

Nota:

Per fare questo è necessario includere il framework QuartzCore.

Swift:

 @import QuartzCore

Objective-C

#import <QuartzCore/QuartzCore.h>

Creazione di particelle con CAEmitterLayer

La classe CAEmitterLayer fornisce un sistema di emittenti di particelle per Core Animation. Le particelle sono definite da istanze di CAEmitterCell .

Le particelle sono disegnate sopra il colore e il bordo dello sfondo del livello.

        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 emettitore con immagine personalizzata

Ad esempio creeremo una vista che contiene il livello di emettitore e anima le particelle.

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

È necessario aggiungere l'immagine "confetti" o definire rect con confetti.contentsRect

Come aggiungere una UIImage a un CALayer

È possibile aggiungere un'immagine a di una vista layer semplicemente utilizzando il suo contents di proprietà:

myView.layer.contents = UIImage(named: "star")?.CGImage
  • Si noti che UIImage deve essere convertito in un CGImage .

Se desideri aggiungere l'immagine nel proprio livello, puoi farlo in questo modo:

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

Modifica l'aspetto

Il codice precedente produce una vista come questa. L'azzurro è l' UIView e la stella blu scuro è UIImage .

immagine stellare su un CALayer

Come puoi vedere, però, sembra pixelato. Questo perché UIImage è più piccolo di UIView quindi viene ridimensionato per riempire la vista, che è l'impostazione predefinita e non specifica altro.

Gli esempi seguenti mostrano variazioni sulla proprietà contentsGravity del contentsGravity del layer. Il codice si presenta così:

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

In iOS, potresti voler impostare la proprietà geometryFlipped su true se stai facendo qualcosa con gravità superiore o inferiore, altrimenti sarà l'opposto di quello che ti aspetti. (Solo la gravità viene ruotata verticalmente, non il rendering del contenuto. Se riscontri problemi con il contenuto capovolto, consulta questa risposta sull'overflow dello stack .)

Ci sono due UIView esempi indicati per ogni contentsGravity impostazione, una vista è maggiore della UIImage e l'altro è più piccolo. In questo modo puoi vedere gli effetti del ridimensionamento e della gravità.

kCAGravityResize

Questo è l'impostazione predefinita.

kCAGravityResize

kCAGravityResizeAspect

kCAGravityResizeAspect

kCAGravityResizeAspectFill

kCAGravityResizeAspectFill

kCAGravityCenter

kCAGravityCenter

kCAGravityTop

kCAGravityTop

kCAGravityBottom

kCAGravityBottom

kCAGravityLeft

kCAGravityLeft

kCAGravityRight

kCAGravityRight

kCAGravityTopLeft

kCAGravityTopLeft

kCAGravityTopRight

kCAGravityTopRight

kCAGravityBottomLeft

kCAGravityBottomLeft

kCAGravityBottomRight

kCAGravityBottomRight

Relazionato

Gli appunti

Aggiungere trasformazioni a un CALayer (tradurre, ruotare, ridimensionare)

Nozioni di base

Ci sono un certo numero di trasformazioni diverse che puoi fare su un livello, ma quelle di base sono

  • tradurre (spostare)
  • scala
  • ruotare

trasformazioni di base

Per eseguire trasformazioni su un CALayer , impostare la proprietà di transform del livello su un tipo CATransform3D . Ad esempio, per tradurre un livello, si dovrebbe fare qualcosa del genere:

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

La parola Make è usata nel nome per creare la trasformazione iniziale: CATransform3D Make Translation. Le trasformazioni successive che vengono applicate omettono il Make . Vedi, per esempio, questa rotazione seguita da una traduzione:

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

Ora che abbiamo le basi su come realizzare una trasformazione, diamo un'occhiata ad alcuni esempi su come fare ognuno di essi. Prima, però, mostrerò come ho impostato il progetto nel caso in cui vogliate giocare con esso.

Impostare

Per gli esempi che seguono ho impostato un'applicazione di visualizzazione singola e aggiunto uno UIView con uno sfondo blu chiaro allo storyboard. Ho collegato la vista al controller della vista con il seguente codice:

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

} 

Esistono molti tipi diversi di CALayer , ma ho scelto di utilizzare CATextLayer modo che le trasformazioni siano visivamente più chiare.

Tradurre

La trasformazione di traduzione sposta il livello. La sintassi di base è

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

dove tx è il cambiamento nelle coordinate x, ty è il cambiamento in y, e tz è il cambiamento in z.

Esempio

traduci esempio

In iOS l'origine del sistema di coordinate è in alto a sinistra, quindi se volessimo spostare il livello di 90 punti verso destra e 50 punti verso il basso, faremo quanto segue:

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

Gli appunti

  • Ricorda che puoi incollarlo nel metodo transformExample() nel codice progetto precedente.
  • Dato che stiamo andando a trattare due dimensioni qui, tz è impostato a 0 .
  • La linea rossa nell'immagine qui sopra va dal centro della posizione originale al centro della nuova posizione. Questo perché le trasformazioni vengono eseguite in relazione al punto di ancoraggio e il punto di ancoraggio di default si trova al centro del livello.

Scala

La scala trasforma tratti o schiaccia il livello. La sintassi di base è

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

dove sx , sy e sz sono i numeri con cui ridimensionare (moltiplicare) le coordinate x, y e z rispettivamente.

Esempio

esempio di scala

Se volessimo metà della larghezza e triplicare l'altezza, faremmo quanto segue

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

Gli appunti

  • Dato che stiamo lavorando solo in due dimensioni, moltiplichiamo le coordinate z per 1.0 per lasciarle inalterate.
  • Il punto rosso nell'immagine sopra rappresenta il punto di ancoraggio. Nota come il ridimensionamento è fatto in relazione al punto di ancoraggio. Cioè, tutto è teso verso o lontano dal punto di ancoraggio.

Ruotare

La trasformazione di rotazione ruota lo strato attorno al punto di ancoraggio (il centro del livello di default). La sintassi di base è

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

dove angle è l'angolo in radianti che lo strato deve essere ruotato e x , y e z sono gli assi su cui ruotare. Impostando un asse su 0 si annulla una rotazione attorno a quel particolare asse.

Esempio

ruotare l'esempio

Se volessimo ruotare uno strato in senso orario di 30 gradi, faremmo quanto segue:

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

Gli appunti

  • Dato che stiamo lavorando in due dimensioni, vogliamo solo che il piano xy sia ruotato attorno all'asse z. Così abbiamo impostato x ed y di 0.0 e impostare z a 1.0 .
  • Questo ha ruotato lo strato in senso orario. Potremmo aver ruotato in senso antiorario impostando z su -1.0 .
  • Il punto rosso indica dove si trova il punto di ancoraggio. La rotazione viene eseguita attorno al punto di ancoraggio.

Trasformazioni multiple

Per combinare più trasformazioni, potremmo usare la concatinazione come questa

CATransform3DConcat(a: CATransform3D, b: CATransform3D)

Tuttavia, faremo solo uno dopo l'altro. La prima trasformazione utilizzerà la Make nel suo nome. Le seguenti trasformazioni non useranno Make , ma prenderanno la trasformazione precedente come parametro.

Esempio

esempio di molte trasformazioni

Questa volta combiniamo tutte e tre le trasformazioni precedenti.

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

Gli appunti

  • L'ordine in cui le trasformazioni sono fatte in materia.
  • Tutto è stato fatto in relazione al punto di ancoraggio (punto rosso).

Una nota su punto di ancoraggio e posizione

Abbiamo fatto tutte le nostre trasformazioni sopra senza cambiare il punto di ancoraggio. A volte è necessario cambiarlo, però, come se si volesse ruotare attorno ad un altro punto oltre al centro. Tuttavia, questo può essere un po 'complicato.

Il punto di ancoraggio e la posizione sono entrambi nello stesso punto. Il punto di ancoraggio è espresso come unità del sistema di coordinate del livello (il valore predefinito è 0.5, 0.5 ) e la posizione è espressa nel sistema di coordinate del superlayer. Possono essere impostati in questo modo

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

Se si imposta solo il punto di ancoraggio senza modificare la posizione, la cornice cambia in modo tale che la posizione si trovi nel punto giusto. O più precisamente, la cornice viene ricalcolata in base al nuovo punto di ancoraggio e alla vecchia posizione. Questo di solito dà risultati inaspettati. I seguenti due articoli hanno un'ottima discussione su questo.

Guarda anche

Questo esempio deriva originariamente da questo esempio di overflow dello stack .

Disabilita animazioni

CALayer animazioni delle proprietà CALayer sono abilitate per impostazione predefinita. Quando questo non è desiderabile, possono essere disabilitati come segue.

veloce

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];

Angoli arrotondati

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

Shadows

Puoi usare 5 proprietà su ogni livello per configurare le tue ombre:

  • shadowOffset : questa proprietà sposta l'ombra a sinistra / a destra o su / giù
self.layer.shadowOffset = CGSizeMake(-1, -1); // 1px left and up

self.layer.shadowOffset = CGSizeMake(1, 1); // 1px down and right
  • shadowColor : imposta il colore della tua ombra
self.layer.shadowColor = [UIColor blackColor].CGColor;
  • shadowOpacity : questa è l'opacità dell'ombra, da 0 a 1
self.layer.shadowOpacity = 0.2;
  • shadowRadius : questo è il raggio di sfocatura (equivalente alla proprietà sfocatura di Sketch o Photoshop)
self.layer.shadowRadius = 6;
  • shadowPath : questa è una proprietà importante per le prestazioni, quando unset di iOS non fa shadowPath l'ombra sul canale alfa della vista, che può richiedere prestazioni elevate con un PNG complesso con alfa. Questa proprietà ti consente di forzare una forma per la tua ombra ed essere più performante a causa di essa.

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
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow