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 enCGImage
.
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
.
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.
kCAGravityResizeAspect
kCAGravityResizeAspectFill
kCAGravityCenter
kCAGravityTop
kCAGravityBottom
kCAGravityLeft
kCAGravityRight
kCAGravityTopLeft
kCAGravityTopRight
kCAGravityBottomLeft
kCAGravityBottomRight
Relaterad
- Innehållsläge för en vy
- Rita en
UIImage
idrawRect
medCGContextDrawImage
- CALayer Tutorial: Komma igång
anteckningar
- Detta exempel kommer ursprungligen från detta Stack Overflow-svar .
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
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
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
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
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
ochy
till0.0
och sätterz
till1.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
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 ärshadowOpacity
opacitet, från0
till1
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