Sök…


Skapa en CALayer

Du kan skapa en CALayer och ställa in dess ram så här:

Snabb:

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

Du kan sedan lägga till det som ett underlag i en befintlig CALayer:

Snabb:

existingLayer.addSublayer(layer)

Objective-C:

[existingLayer addSublayer:layer];

Notera:

För att göra detta måste du inkludera QuartzCore-ramverket.

Snabb:

 @import QuartzCore

Objective-C

#import <QuartzCore/QuartzCore.h>

Skapa partiklar med CAEmitterLayer

Klassen CAEmitterLayer tillhandahåller ett partikelemitter-system för Core Animation. Partiklarna definieras av fall av CAEmitterCell .

Partiklarna dras över skiktets bakgrundsfärg och kant.

        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)

Emitter View med anpassad bild

Till exempel kommer vi att skapa en vy som innehåller emitterlager och animerar partiklar.

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

Du måste lägga till "konfetti" -bild eller definiera rect med confetti.contentsRect

Hur du lägger till en UII-bild till en CALayer

Du kan lägga till en bild i vyns layer helt enkelt genom att använda dess contents :

myView.layer.contents = UIImage(named: "star")?.CGImage
  • Observera att UIImage måste konverteras till en CGImage .

Om du vill lägga till bilden i sitt eget lager kan du göra det så här:

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

Ändra utseendet

Ovanstående kod ger en vy som denna. Den ljusblåa är UIView och den mörkblå stjärnan är UIImage .

stjärnbild på en CALayer

Men som du ser ser det ut pixelat. Detta beror på att UIImage är mindre än UIView så att den skalas för att fylla vyn, vilket är standard, det anger du inte något annat.

Exemplen nedan visar variationer på skiktets contentsGravity egenskap. Koden ser ut så här:

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

I iOS kanske du vill ställa in geometryFlipped egenskapen till true om du gör något med topp- eller bottenvikt, annars blir det motsatsen till vad du förväntar dig. (Endast tyngdekraften vänds vertikalt, inte innehållsindelningen. Om du har problem med att innehållet ska vändas, se detta Stack Overflow-svar .)

Det finns två UIView exempel nedan för varje contentsGravity inställning, en vy är större än UIImage och den andra är mindre. På detta sätt kan du se effekterna av skalningen och tyngdkraften.

kCAGravityResize

Detta är standard.

kCAGravityResize

kCAGravityResizeAspect

kCAGravityResizeAspect

kCAGravityResizeAspectFill

kCAGravityResizeAspectFill

kCAGravityCenter

kCAGravityCenter

kCAGravityTop

kCAGravityTop

kCAGravityBottom

kCAGravityBottom

kCAGravityLeft

kCAGravityLeft

kCAGravityRight

kCAGravityRight

kCAGravityTopLeft

kCAGravityTopLeft

kCAGravityTopRight

kCAGravityTopRight

kCAGravityBottomLeft

kCAGravityBottomLeft

kCAGravityBottomRight

kCAGravityBottomRight

Relaterad

anteckningar

Lägga till transformer till en CALayer (översätta, rotera, skala)

Grunderna

Det finns ett antal olika omvandlingar du kan göra på ett lager, men de grundläggande är det

  • översätta (flytta)
  • skala
  • rotera

grundläggande omvandlingar

För att göra transformationer på en CALayer du in lagrets transform till en CATransform3D typ. Till exempel, för att översätta ett lager, skulle du göra något liknande:

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

Ordet Make används i namnet för att skapa den initiala omvandlingen: CATransform3D Make Translation. Efterföljande omvandlingar som tillämpas utelämnar Make . Se till exempel denna rotation följt av en översättning:

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

Nu när vi har grunden för hur man gör en omvandling, låt oss titta på några exempel på hur man gör var och en. Men först kommer jag dock att visa hur jag skapar projektet om du också vill spela med det.

Uppstart

För följande exempel UIView ett UIView med en enskild vy och lade till en UIView med ljusblå bakgrund till storyboard. Jag kopplade upp vyn till visningskontrollern med följande kod:

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

} 

Det finns många olika typer av CALayer , men jag valde att använda CATextLayer så att transformeringarna blir tydligare visuellt.

Översätt

Översättningstransformen flyttar lagret. Den grundläggande syntaxen är

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

där tx är förändringen i x-koordinaterna, ty är förändringen i y och tz är förändringen i z.

Exempel

översätta exempel

I iOS är koordinatsystemets ursprung uppe till vänster, så om vi ville flytta lagret 90 punkter till höger och 50 punkter nedåt, skulle vi göra följande:

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

anteckningar

  • Kom ihåg att du kan klistra in detta i metoden transformExample() i projektkoden ovan.
  • Eftersom vi bara kommer att ta itu med två dimensioner här är tz inställt på 0 .
  • Den röda linjen i bilden ovan går från mitten av den ursprungliga platsen till mitten av den nya platsen. Det beror på att transformationer görs i förhållande till förankringspunkten och förankringspunkten är som standard mitt i skiktet.

Skala

Skalaomvandlingen sträcker eller klämmer ut skiktet. Den grundläggande syntaxen är

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

där sx , sy och sz är siffrorna för att skala (multiplicera) x-, y- och z-koordinaterna.

Exempel

skala exempel

Om vi ville halva bredden och tredubbla höjden, skulle vi göra följande

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

anteckningar

  • Eftersom vi bara arbetar i två dimensioner multiplicerar vi bara z-koordinaterna med 1,0 för att lämna dem opåverkade.
  • Den röda pricken i bilden ovan representerar förankringspunkten. Lägg märke till hur skalningen görs i förhållande till förankringspunkten. Det vill säga allt sträcker sig mot eller bort från förankringspunkten.

Rotera

Rotationstransformationen roterar lagret runt förankringspunkten (skiktets centrum som standard). Den grundläggande syntaxen är

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

där angle är vinkeln i radianer som skiktet ska roteras och x , y och z är axlarna som ska roteras. Att ställa in en axel till 0 avbryter en rotation runt den aktuella axeln.

Exempel

rotera exempel

Om vi ville rotera ett lager medurs 30 grader, skulle vi göra följande:

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

anteckningar

  • Eftersom vi arbetar i två mått vill vi bara att xy-planet roteras runt z-axeln. Således sätter vi x och y till 0.0 och sätter z till 1.0 .
  • Detta roterade skiktet medurs. Vi kunde ha roterat moturs genom att ställa in z till -1.0 .
  • Den röda pricken visar var ankarpunkten är. Rotationen utförs runt förankringspunkten.

Flera omvandlingar

För att kombinera flera transformationer kan vi använda konkatination som denna

CATransform3DConcat(a: CATransform3D, b: CATransform3D)

Men vi kommer bara att göra en efter en. Den första omvandlingen kommer att använda Make i dess namn. Följande omvandlingar använder inte Make , men de kommer att ta den föregående transformeringen som en parameter.

Exempel

exempel på flera transformer

Den här gången kombinerar vi alla de tre tidigare transformerna.

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

anteckningar

  • Ordningen att transformeringarna görs i frågor.
  • Allt gjordes i förhållande till förankringspunkten (röd prick).

En anmärkning om ankarpunkt och position

Vi gjorde alla våra transformationer ovan utan att ändra ankarpunkten. Ibland är det dock nödvändigt att ändra den, som om du vill rotera runt någon annan punkt förutom centrum. Detta kan dock vara lite knepigt.

Förankringspunkten och positionen är båda på samma plats. Förankringspunkten uttrycks som en enhet i lagrets koordinatsystem (standard är 0.5, 0.5 ) och positionen uttrycks i superlagerns koordinatsystem. De kan ställas in så här

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

Om du bara ställer in förankringspunkten utan att ändra position, ändras ramen så att positionen kommer att vara på rätt plats. Eller mer exakt, ramen beräknas om baserat på den nya förankringspunkten och gamla position. Detta ger vanligtvis oväntade resultat. Följande två artiklar har en utmärkt diskussion om detta.

Se även

Detta exempel kommer ursprungligen från detta Stack Overflow-exempel .

Inaktivera animationer

CALayer egendomsanimationer är aktiverade som standard. När detta är oönskat kan de inaktiveras enligt följande.

Snabb

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

Rundade hörn

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

skuggor

Du kan använda 5 egenskaper på varje lager för att konfigurera dina skuggor:

  • shadowOffset - den här egenskapen flyttar din skugga åt vänster / höger eller upp / ner
self.layer.shadowOffset = CGSizeMake(-1, -1); // 1px left and up

self.layer.shadowOffset = CGSizeMake(1, 1); // 1px down and right
  • shadowColor - detta ställer in färgen på din skugga
self.layer.shadowColor = [UIColor blackColor].CGColor;
  • shadowOpacity - det här är shadowOpacity opacitet, från 0 till 1
self.layer.shadowOpacity = 0.2;
  • shadowRadius - detta är suddighetsradie (motsvarande suddighetsegenskapen i Sketch eller Photoshop)
self.layer.shadowRadius = 6;
  • shadowPath - detta är en viktig egenskap för prestanda, när iOS inte är baserat skuggan på vykans alfakanal, vilket kan vara prestandaintensivt med en komplex PNG med alfa. Den här egenskapen låter dig tvinga en form för din skugga och vara mer framträdande på grund av den.

Objective-C

self.layer.shadowPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0,100,100)]; //this does a circular shadow

Snabb 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
Licensierat under CC BY-SA 3.0
Inte anslutet till Stack Overflow