Zoeken…


Een CALayer maken

U kunt een CALayer maken en het frame als volgt instellen:

Snel:

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

Doelstelling C:

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

U kunt het vervolgens als een sublaag toevoegen aan een bestaande CALayer:

Snel:

existingLayer.addSublayer(layer)

Doelstelling C:

[existingLayer addSublayer:layer];

Notitie:

Om dit te doen, moet u het QuartzCore-framework opnemen.

Snel:

 @import QuartzCore

Doelstelling C

#import <QuartzCore/QuartzCore.h>

Deeltjes maken met CAEmitterLayer

De CAEmitterLayer- klasse biedt een deeltjesemittersysteem voor Core Animation. De deeltjes worden gedefinieerd door instanties van CAEmitterCell .

De deeltjes worden boven de achtergrondkleur en rand van de laag getekend.

        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)

Zenderweergave met aangepaste afbeelding

We zullen bijvoorbeeld een weergave maken die een emitterlaag bevat en deeltjes animeert.

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

U moet een afbeelding "confetti" toevoegen of rect definiëren met confetti.contentsRect

Een UII-afbeelding toevoegen aan een CALayer

U kunt een afbeelding eenvoudig aan de layer van een weergave toevoegen met de eigenschap contents :

myView.layer.contents = UIImage(named: "star")?.CGImage
  • Merk op dat de UIImage moet worden geconverteerd naar een CGImage .

Als u de afbeelding in zijn eigen laag wilt toevoegen, kunt u dit als volgt doen:

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

Het uiterlijk wijzigen

De bovenstaande code produceert een dergelijke weergave. Het lichtblauw is de UIView en de donkerblauwe ster is de UIImage .

sterafbeelding op een CALayer

Zoals je ziet, ziet het er echter korrelig uit. Dit komt omdat de UIImage afbeelding kleiner is dan de UIView zodat deze wordt geschaald om de weergave te vullen. Dit is de standaardinstelling die u niets anders opgeeft.

De voorbeelden hieronder tonen variaties op de laag contentsGravity objecten. De code ziet er zo uit:

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

In iOS wilt u misschien de eigenschap geometryFlipped op true als u iets doet met zwaartekracht boven of onder, anders is dit het tegenovergestelde van wat u verwacht. (Alleen de zwaartekracht wordt verticaal omgedraaid, niet de weergave van de inhoud. Als u problemen ondervindt met de inhoud die wordt omgedraaid, zie dan dit antwoord Stack Overflow .)

Er zijn twee UIView voorbeelden hieronder voor elke contentsGravity Zwaartekrachtinstelling, één weergave is groter dan de UIImage afbeelding en de andere is kleiner. Op deze manier kunt u de effecten van de schaalverdeling en de zwaartekracht zien.

kCAGravityResize

Dit is de standaardinstelling.

kCAGravityResize

kCAGravityResizeAspect

kCAGravityResizeAspect

kCAGravityResizeAspectFill

kCAGravityResizeAspectFill

kCAGravityCenter

kCAGravityCenter

kCAGravityTop

kCAGravityTop

kCAGravityBottom

kCAGravityBottom

kCAGravityLeft

kCAGravityLeft

kCAGravityRight

kCAGravityRight

kCAGravityTopLeft

kCAGravityTopLeft

kCAGravityTopRight

kCAGravityTopRight

kCAGravityBottomLeft

kCAGravityBottomLeft

kCAGravityBottomRight

kCAGravityBottomRight

Verwant

Notes

Transformaties toevoegen aan een CALayer (vertalen, roteren, schalen)

Basics

Er zijn een aantal verschillende transformaties die je op een laag kunt doen, maar de basis zijn dat

  • vertalen (verplaatsen)
  • schaal
  • draaien

basistransformaties

Als u transformaties op een CALayer , stelt u de eigenschap transform de laag in op een CATransform3D type. Als u bijvoorbeeld een laag wilt vertalen, zou u zoiets doen:

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

Het woord Make wordt gebruikt in de naam voor het maken van de eerste transformatie: CATransform3D Make Translation. Latere transformaties die worden toegepast weglaten de Make . Zie bijvoorbeeld deze rotatie gevolgd door een vertaling:

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

Nu we de basis hebben voor het maken van een transformatie, laten we eens kijken naar enkele voorbeelden van hoe je ze allemaal kunt doen. Eerst zal ik echter laten zien hoe ik het project heb opgezet voor het geval je er ook mee wilt spelen.

Opstelling

Voor de volgende voorbeelden heb ik een Single View-applicatie opgezet en een UIView met een lichtblauwe achtergrond aan het storyboard toegevoegd. Ik heb de weergave gekoppeld aan de weergavecontroller met de volgende code:

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

} 

Er zijn veel verschillende soorten CALayer , maar ik heb ervoor gekozen CATextLayer te gebruiken zodat de transformaties visueel duidelijker worden.

Vertalen

De vertaaltransformatie verplaatst de laag. De basissyntaxis is

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

waarbij tx de verandering in de x-coördinaten is, ty de verandering in y is en tz de verandering in z.

Voorbeeld

vertaal voorbeeld

In iOS bevindt de oorsprong van het coördinatensysteem zich linksboven, dus als we de laag 90 punten naar rechts en 50 punten naar beneden wilden verplaatsen, zouden we het volgende doen:

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

Notes

  • Vergeet niet dat u dit in de methode transformExample() in de bovenstaande projectcode kunt plakken.
  • Omdat we hier slechts twee dimensies gaan behandelen, is tz ingesteld op 0 .
  • De rode lijn in de bovenstaande afbeelding gaat van het midden van de oorspronkelijke locatie naar het midden van de nieuwe locatie. Dat komt omdat transformaties worden uitgevoerd in relatie tot het ankerpunt en het ankerpunt standaard in het midden van de laag staat.

Schaal

De schaaltransformatie rekt de laag uit of squishet. De basissyntaxis is

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

waarbij sx , sy en sz de getallen zijn waarmee respectievelijk de x-, y- en z-coördinaten kunnen worden geschaald (vermenigvuldigd).

Voorbeeld

schaalvoorbeeld

Als we de helft van de breedte en de hoogte zouden verdrievoudigen, zouden we het volgende doen

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

Notes

  • Omdat we slechts in twee dimensies werken, vermenigvuldigen we gewoon de z-coördinaten met 1.0 om ze onaangetast te laten.
  • De rode stip in de bovenstaande afbeelding vertegenwoordigt het ankerpunt. Merk op hoe de schaling wordt uitgevoerd in relatie tot het ankerpunt. Dat wil zeggen, alles is ofwel uitgerekt naar of weg van het ankerpunt.

Draaien

De rotatietransformatie roteert de laag rond het ankerpunt (standaard het midden van de laag). De basissyntaxis is

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

waarbij angle de hoek in radialen is die de laag moet worden geroteerd en x , y en z de assen zijn waarover moet worden geroteerd. Als u een as op 0 instelt, wordt een rotatie rond die specifieke as geannuleerd.

Voorbeeld

roteer voorbeeld

Als we een laag 30 graden rechtsom zouden willen draaien, zouden we het volgende doen:

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

Notes

  • Omdat we in twee dimensies werken, willen we alleen dat het xy-vlak rond de z-as wordt gedraaid. Dus stellen we x en y op 0.0 en stellen z op 1.0 .
  • Dit roteerde de laag met de klok mee. We hadden tegen de klok in kunnen draaien door z te stellen op -1.0 .
  • De rode stip geeft aan waar het ankerpunt is. De rotatie gebeurt rond het ankerpunt.

Meerdere transformaties

Om meerdere transformaties te combineren, kunnen we concatinatie als deze gebruiken

CATransform3DConcat(a: CATransform3D, b: CATransform3D)

We zullen echter gewoon de een na de ander doen. De eerste transformatie zal het Make in zijn naam gebruiken. De volgende transformaties gebruiken Make , maar ze nemen de vorige transformatie als parameter.

Voorbeeld

meerdere transformaties bijvoorbeeld

Deze keer combineren we alle drie de vorige transformaties.

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

Notes

  • De volgorde waarin de transformaties worden uitgevoerd in zaken.
  • Alles werd gedaan in relatie tot het ankerpunt (rode stip).

Een opmerking over ankerpunt en positie

We hebben al onze transformaties hierboven uitgevoerd zonder het ankerpunt te wijzigen. Soms is het echter nodig om het te wijzigen, bijvoorbeeld als u rond een ander punt naast het midden wilt roteren. Dit kan echter een beetje lastig zijn.

Het ankerpunt en de positie bevinden zich beide op dezelfde plaats. Het ankerpunt wordt uitgedrukt als een eenheid van het coördinatensysteem van de laag (standaard is 0.5, 0.5 ) en de positie wordt uitgedrukt in het coördinatensysteem van de superlaag. Ze kunnen zo worden ingesteld

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

Als u alleen het ankerpunt instelt zonder de positie te wijzigen, verandert het frame zodat de positie op de juiste plek staat. Of beter gezegd, het frame wordt opnieuw berekend op basis van het nieuwe ankerpunt en de oude positie. Dit geeft meestal onverwachte resultaten. In de volgende twee artikelen wordt dit uitstekend besproken.

Zie ook

Dit voorbeeld komt oorspronkelijk uit dit Stack Overflow-voorbeeld .

Animaties uitschakelen

CALayer eigenschapanimaties zijn standaard ingeschakeld. Wanneer dit ongewenst is, kunnen ze als volgt worden uitgeschakeld.

Snel

CATransaction.begin()
CATransaction.setDisableActions(true)

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

CATransaction.commit()

Doelstelling C

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

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

[CATransaction commit];

Afgeronde hoeken

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

Shadows

U kunt op elke laag 5 eigenschappen gebruiken om uw schaduwen te configureren:

  • shadowOffset - deze eigenschap verplaatst je schaduw naar links / rechts of omhoog / omlaag
self.layer.shadowOffset = CGSizeMake(-1, -1); // 1px left and up

self.layer.shadowOffset = CGSizeMake(1, 1); // 1px down and right
  • shadowColor - dit bepaalt de kleur van je schaduw
self.layer.shadowColor = [UIColor blackColor].CGColor;
  • shadowOpacity - dit is de dekking van de schaduw, van 0 tot 1
self.layer.shadowOpacity = 0.2;
  • shadowRadius - dit is de vervagingsradius (equivalent van de vervagingseigenschap in Sketch of Photoshop)
self.layer.shadowRadius = 6;
  • shadowPath - dit is een belangrijke eigenschap voor prestaties, wanneer uitgeschakeld iOS de schaduw baseert op het alfakanaal van de weergave, dat prestatie-intensief kan zijn met een complexe PNG met alpha. Met deze eigenschap kunt u een vorm voor uw schaduw afdwingen en daardoor beter presteren.

Doelstelling 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
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow