Suche…
Einen CALayer erstellen
Sie können einen CALayer erstellen und seinen Rahmen folgendermaßen festlegen:
Schnell:
let layer = CALayer()
layer.frame = CGRect(x: 0, y: 0, width: 60, height: 80)
Ziel c:
CALayer *layer = [[CALayer alloc] init];
layer.frame = CGRectMake(0, 0, 60, 80);
Sie können es dann als Sublayer zu einem vorhandenen CALayer hinzufügen:
Schnell:
existingLayer.addSublayer(layer)
Ziel c:
[existingLayer addSublayer:layer];
Hinweis:
Dazu müssen Sie das QuartzCore-Framework einbeziehen.
Schnell:
@import QuartzCore
Ziel c
#import <QuartzCore/QuartzCore.h>
Partikel mit CAEmitterLayer erstellen
Die CAEmitterLayer- Klasse stellt ein Partikelemittersystem für Core-Animation bereit. Die Partikel werden durch CAEmitterCell- Instanzen definiert .
Die Partikel werden über der Hintergrundfarbe und dem Rand der Ebene gezeichnet.
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-Ansicht mit benutzerdefiniertem Bild
Zum Beispiel erstellen wir eine Ansicht, die die Emitter-Ebene enthält und Partikel animiert.
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
}
}
Sie müssen ein "confetti" -Bild hinzufügen oder mit confetti.contentsRect "rect" definieren
So fügen Sie einen UIImage zu einem CALayer hinzu
Sie können der layer
einer Ansicht einfach ein Bild hinzufügen, indem Sie dessen contents
:
myView.layer.contents = UIImage(named: "star")?.CGImage
- Beachten Sie, dass der
UIImage
in einCGImage
konvertiert werdenCGImage
.
Wenn Sie das Bild in einer eigenen Ebene hinzufügen möchten, können Sie dies folgendermaßen tun:
let myLayer = CALayer()
let myImage = UIImage(named: "star")?.CGImage
myLayer.frame = myView.bounds
myLayer.contents = myImage
myView.layer.addSublayer(myLayer)
Erscheinungsbild ändern
Der obige Code erzeugt eine Ansicht wie diese. Das helle Blau ist die UIView
und der dunkelblaue Stern ist der UIImage
.
Wie Sie sehen, sieht es jedoch pixelig aus. Dies liegt daran, dass der UIImage
kleiner ist als die UIView
so dass er so skaliert wird, dass er die Ansicht ausfüllt. Dies ist der Standard, wenn Sie nichts anderes angeben.
Die folgenden Beispiele zeigen Variationen der Eigenschaft contentsGravity
der Ebene. Der Code sieht so aus:
myView.layer.contents = UIImage(named: "star")?.CGImage
myView.layer.contentsGravity = kCAGravityTop
myView.layer.geometryFlipped = true
In iOS möchten Sie möglicherweise die Eigenschaft geometryFlipped
auf true
wenn Sie mit der oberen oder unteren Schwerkraft arbeiten. Andernfalls ist dies das Gegenteil von dem, was Sie erwarten. (Nur die Schwerkraft wird vertikal umgedreht, nicht das Rendern von Inhalten. Wenn Sie Probleme mit dem umgedrehten Inhalt haben, lesen Sie diese Stack Overflow-Antwort .)
Es gibt zwei UIView
Beispiele unten für jede contentsGravity
Einstellung ist eine Ansicht größer als die UIImage
und der andere kleiner. Auf diese Weise können Sie die Auswirkungen der Skalierung und der Schwerkraft erkennen.
kCAGravityResize
Dies ist die Standardeinstellung.
kCAGravityResizeAspect
kCAGravityResizeAspectFill
kCAGravityCenter
kCAGravityTop
kCAGravityBottom
kCAGravityLeft
kCAGravityRight
kCAGravityTopLeft
kCAGravityTopRight
kCAGravityBottomLeft
kCAGravityBottomRight
verbunden
- Eigenschaft des Inhaltsmodus einer Ansicht
- Zeichnen eines
UIImage
indrawRect
mitCGContextDrawImage
- CALayer-Tutorial: Erste Schritte
Anmerkungen
- Dieses Beispiel stammt ursprünglich aus dieser Stack Overflow-Antwort .
Transformationen zu einem CALayer hinzufügen (übersetzen, drehen, skalieren)
Grundlagen
Es gibt eine Reihe verschiedener Transformationen, die Sie auf einer Ebene ausführen können, aber die grundlegenden sind dies
- übersetzen (bewegen)
- Rahmen
- drehen
Um Transformationen für einen CALayer
, setzen Sie die transform
des Layers auf einen CATransform3D
Typ. Um eine Ebene zu übersetzen, würden Sie beispielsweise Folgendes tun:
myLayer.transform = CATransform3DMakeTranslation(20, 30, 0)
Das Wort Make
wird im Namen zum Erstellen der ursprünglichen Transformation verwendet: CATransform3D Make Translation. Nachfolgende Transformationen, die angewendet werden, lassen das Make
. Siehe zum Beispiel diese Rotation gefolgt von einer Übersetzung:
let rotation = CATransform3DMakeRotation(CGFloat(30.0 * M_PI / 180.0), 20, 20, 0)
myLayer.transform = CATransform3DTranslate(rotation, 20, 30, 0)
Da wir nun die Grundlage dafür haben, wie eine Transformation durchgeführt werden kann, wollen wir uns einige Beispiele ansehen, wie sie jeweils ausgeführt werden können. Zuerst werde ich jedoch zeigen, wie ich das Projekt aufbaue, falls Sie auch damit herumspielen wollen.
Konfiguration
Für die folgenden Beispiele habe ich eine UIView
Anwendung eingerichtet und dem Storyboard eine UIView
mit hellblauem Hintergrund hinzugefügt. Ich habe die Ansicht mit dem folgenden Code an den View-Controller angeschlossen:
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 ...
}
}
Es gibt viele verschiedene Arten von CALayer
, aber ich entschied mich für CATextLayer
damit die Transformationen visuell klarer werden.
Übersetzen
Die Übersetzungstransformation verschiebt die Ebene. Die grundlegende Syntax lautet
CATransform3DMakeTranslation(tx: CGFloat, ty: CGFloat, tz: CGFloat)
Dabei ist tx
die Änderung in den x-Koordinaten, ty
ist die Änderung in y und tz
ist die Änderung in z.
Beispiel
Bei iOS befindet sich der Ursprung des Koordinatensystems oben links. Wenn wir also die Ebene um 90 Punkte nach rechts und 50 Punkte nach unten verschieben möchten, würden wir Folgendes tun:
myLayer.transform = CATransform3DMakeTranslation(90, 50, 0)
Anmerkungen
- Denken Sie daran, dass Sie dies im obigen Projektcode in die
transformExample()
Methode einfügen können. - Da wir uns hier nur mit zwei Dimensionen befassen, wird
tz
auf0
. - Die rote Linie im obigen Bild verläuft von der Mitte des ursprünglichen Orts bis zur Mitte des neuen Orts. Das liegt daran, dass Transformationen in Bezug auf den Ankerpunkt durchgeführt werden und der Ankerpunkt standardmäßig in der Mitte der Ebene liegt.
Rahmen
Die Skalentransformation dehnt oder zerquetscht die Ebene. Die grundlegende Syntax lautet
CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat)
Dabei sind sx
, sy
und sz
die Zahlen, mit denen die x-, y- bzw. z-Koordinaten skaliert (multipliziert) werden sollen.
Beispiel
Wenn wir die Breite halbieren und die Höhe verdreifachen wollten, würden wir Folgendes tun
myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)
Anmerkungen
- Da wir nur in zwei Dimensionen arbeiten, multiplizieren wir einfach die z-Koordinaten mit 1,0, um sie nicht zu beeinflussen.
- Der rote Punkt im Bild oben repräsentiert den Ankerpunkt. Beachten Sie, wie die Skalierung im Verhältnis zum Ankerpunkt erfolgt. Das heißt, alles ist entweder zum Ankerpunkt hin oder von ihm weg gestreckt.
Drehen
Die Rotationstransformation dreht die Ebene um den Ankerpunkt (standardmäßig die Mitte der Ebene). Die grundlegende Syntax lautet
CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat)
Dabei ist angle
der Winkel, um den die Ebene gedreht werden soll, und x
, y
und z
sind die Achsen, um die gedreht werden soll. Wenn Sie eine Achse auf 0 setzen, wird die Drehung um diese bestimmte Achse abgebrochen.
Beispiel
Wenn wir eine Ebene um 30 Grad im Uhrzeigersinn drehen möchten, würden wir Folgendes tun:
let degrees = 30.0
let radians = CGFloat(degrees * M_PI / 180)
myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)
Anmerkungen
- Da wir in zwei Dimensionen arbeiten, möchten wir nur, dass die xy-Ebene um die z-Achse gedreht wird. Also setzen wir
x
undy
auf0.0
undz
auf1.0
. - Dadurch wurde die Ebene im Uhrzeigersinn gedreht. Wir hätten uns gegen den Uhrzeigersinn drehen können, indem wir
z
auf-1.0
. - Der rote Punkt zeigt, wo sich der Ankerpunkt befindet. Die Drehung erfolgt um den Ankerpunkt.
Mehrere Transformationen
Um mehrere Transformationen zu kombinieren, können wir die Concatination wie folgt verwenden
CATransform3DConcat(a: CATransform3D, b: CATransform3D)
Wir werden jedoch nur einen nach dem anderen machen. Die erste Transformation verwendet das Make
im Namen. Bei den folgenden Transformationen wird Make
nicht verwendet, die vorherige Transformation wird jedoch als Parameter verwendet.
Beispiel
Diesmal kombinieren wir alle drei der vorherigen Transformationen.
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
Anmerkungen
- Die Reihenfolge, in der die Transformationen durchgeführt werden.
- Alles wurde in Bezug auf den Ankerpunkt (roter Punkt) gemacht.
Ein Hinweis zu Ankerpunkt und Position
Wir haben alle unsere Transformationen oben durchgeführt, ohne den Ankerpunkt zu ändern. Manchmal ist es jedoch notwendig, sie zu ändern, als ob Sie sich um einen anderen Punkt außer der Mitte drehen möchten. Dies kann jedoch etwas schwierig sein.
Der Ankerpunkt und die Position befinden sich an derselben Stelle. Der Ankerpunkt wird als Einheit des Koordinatensystems der Ebene angegeben (Standardeinstellung ist 0.5, 0.5
), und die Position wird im Koordinatensystem der Überlagerung angegeben. Sie können so eingestellt werden
myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
myLayer.position = CGPoint(x: 50, y: 50)
Wenn Sie nur den Ankerpunkt festlegen, ohne die Position zu ändern, ändert sich der Rahmen, sodass die Position an der richtigen Stelle ist. Oder genauer, der Rahmen wird basierend auf dem neuen Ankerpunkt und der alten Position neu berechnet. Dies führt normalerweise zu unerwarteten Ergebnissen. Die folgenden zwei Artikel haben eine ausgezeichnete Diskussion darüber.
Siehe auch
-
CALayer
, abgerundete Ecken und Schatten auf einemCALayer
- Verwenden eines Rahmens mit einem Bezier-Pfad für eine Ebene
Dieses Beispiel stammt ursprünglich aus diesem Stack Overflow-Beispiel .
Animationen deaktivieren
CALayer
Eigenschaftsanimationen sind standardmäßig aktiviert. Wenn dies unerwünscht ist, können sie wie folgt deaktiviert werden.
Schnell
CATransaction.begin()
CATransaction.setDisableActions(true)
// change layer properties that you don't want to animate
CATransaction.commit()
Ziel c
[CATransaction begin];
[CATransaction setDisableActions:YES];
// change layer properties that you don't want to animate
[CATransaction commit];
Abgerundete Ecken
layer.masksToBounds = true;
layer.cornerRadius = 8;
Schatten
Sie können 5 Eigenschaften auf jeder Ebene verwenden, um Ihre Schatten zu konfigurieren:
-
shadowOffset
- Diese Eigenschaft bewegt Ihren Schatten nach links / rechts oder nach oben / unten
self.layer.shadowOffset = CGSizeMake(-1, -1); // 1px left and up
self.layer.shadowOffset = CGSizeMake(1, 1); // 1px down and right
-
shadowColor
- legt die Farbe Ihres Schattens fest
self.layer.shadowColor = [UIColor blackColor].CGColor;
-
shadowOpacity
- Dies ist die Deckkraft des Schattens von0
bis1
self.layer.shadowOpacity = 0.2;
-
shadowRadius
- Dies ist der Unschärfekreis (entspricht der Unschärfe-Eigenschaft in Sketch oder Photoshop).
self.layer.shadowRadius = 6;
-
shadowPath
- Dies ist eine wichtige Eigenschaft für die Leistung, wenn nicht festgelegtes iOS den Schatten auf dem Alphakanal der AnsichtshadowPath
Dies kann bei einer komplexen PNG mit Alpha die Leistung beeinträchtigen. Mit dieser Eigenschaft können Sie eine Form für Ihren Schatten erzwingen und dadurch leistungsfähiger werden.
Ziel 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