Szukaj…
Tworzenie CALayer
Możesz utworzyć CALayer i ustawić jego ramkę w następujący sposób:
Szybki:
let layer = CALayer()
layer.frame = CGRect(x: 0, y: 0, width: 60, height: 80)
Cel C:
CALayer *layer = [[CALayer alloc] init];
layer.frame = CGRectMake(0, 0, 60, 80);
Następnie możesz dodać go jako podwarstwę do istniejącej CALayer:
Szybki:
existingLayer.addSublayer(layer)
Cel C:
[existingLayer addSublayer:layer];
Uwaga:
Aby to zrobić, musisz dołączyć platformę QuartzCore.
Szybki:
@import QuartzCore
Cel C
#import <QuartzCore/QuartzCore.h>
Tworzenie cząstek za pomocą CAEmitterLayer
Klasa CAEmitterLayer zapewnia system emitujący cząstki dla Core Animation. Cząstki są zdefiniowane przez instancje CAEmitterCell .
Cząsteczki są rysowane powyżej koloru tła i obramowania warstwy.
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)
Widok emitera z niestandardowym obrazem
Na przykład stworzymy widok, który zawiera warstwę emitera i animuje cząsteczki.
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
}
}
Musisz dodać obraz „konfetti” lub zdefiniować rect za pomocą confetti.contentsRect
Jak dodać UIImage do CALayer
Możesz dodać obraz do layer
widoku, po prostu używając jego właściwości contents
:
myView.layer.contents = UIImage(named: "star")?.CGImage
- Pamiętaj, że
UIImage
musi zostać przekonwertowany naCGImage
.
Jeśli chcesz dodać obraz we własnej warstwie, możesz to zrobić w następujący sposób:
let myLayer = CALayer()
let myImage = UIImage(named: "star")?.CGImage
myLayer.frame = myView.bounds
myLayer.contents = myImage
myView.layer.addSublayer(myLayer)
Modyfikowanie wyglądu
Powyższy kod tworzy taki widok. Jasnoniebieski to UIView
a ciemnoniebieska gwiazda to UIImage
.
Jak widać, wygląda na pikselowany. Wynika to z faktu, że UIImage
jest mniejszy niż UIView
dlatego jest skalowany w celu wypełnienia widoku. Domyślnie nie określa się niczego innego.
Poniższe przykłady pokazują, Wariacje na warstwy contentsGravity
nieruchomości. Kod wygląda następująco:
myView.layer.contents = UIImage(named: "star")?.CGImage
myView.layer.contentsGravity = kCAGravityTop
myView.layer.geometryFlipped = true
W iOS możesz ustawić właściwość geometryFlipped
na true
jeśli robisz cokolwiek z górną lub dolną grawitacją, w przeciwnym razie będzie odwrotnie niż się spodziewasz. (Tylko grawitacja jest odwracana w pionie, a nie renderowanie zawartości. Jeśli masz problemy z odwracaniem zawartości, zapoznaj się z odpowiedzią na Przepełnienie stosu .)
Istnieją dwa przykłady UIView
dla każdego ustawienia contentsGravity
, jeden widok jest większy niż UIImage
a drugi jest mniejszy. W ten sposób możesz zobaczyć efekty skalowania i grawitacji.
kCAGravityResize
To jest domyślne.
kCAGravityResizeAspect
kCAGravityResizeAspectFill
kCAGravityCenter
kCAGravityTop
kCAGravityBottom
kCAGravityLeft
kCAGravityRight
kCAGravityTopLeft
kCAGravityTopRight
kCAGravityBottomLeft
kCAGravityBottomRight
Związane z
- Właściwość trybu zawartości widoku
- Rysowanie
UIImage
wdrawRect
pomocąCGContextDrawImage
- Samouczek CALayer: Pierwsze kroki
Notatki
- Ten przykład pochodzi pierwotnie z tej odpowiedzi Przepełnienie stosu .
Dodawanie transformacji do CALayer (tłumacz, obracaj, skaluj)
Podstawy
Na warstwie można wykonać wiele różnych transformacji, ale podstawowe są
- przetłumacz (przenieś)
- skala
- obracać się
Aby wykonać transformację na CALayer
, ustaw właściwość transform
warstwy na typ CATransform3D
. Na przykład, aby przetłumaczyć warstwę, zrobiłbyś coś takiego:
myLayer.transform = CATransform3DMakeTranslation(20, 30, 0)
Słowo Make
jest używane w nazwie do utworzenia początkowej transformacji: CATransform3D Make Translation. Kolejne zastosowane transformacje pomijają opcję Make
. Zobacz na przykład ten obrót, a następnie tłumaczenie:
let rotation = CATransform3DMakeRotation(CGFloat(30.0 * M_PI / 180.0), 20, 20, 0)
myLayer.transform = CATransform3DTranslate(rotation, 20, 30, 0)
Teraz, gdy mamy podstawy, jak dokonać transformacji, spójrzmy na kilka przykładów, jak to zrobić. Najpierw jednak pokażę, jak skonfigurowałem projekt na wypadek, gdybyś chciał się nim bawić.
Ustawiać
W poniższych przykładach skonfigurowałem aplikację Single View i dodałem UIView
z jasnoniebieskim tłem do scenorysu. Podłączyłem widok do kontrolera widoku za pomocą następującego kodu:
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 ...
}
}
Istnieje wiele różnych rodzajów CALayer
, ale zdecydowałem się użyć CATextLayer
aby transformacje były wyraźniejsze wizualnie.
Tłumaczyć
Transformacja translacji przesuwa warstwę. Podstawowa składnia to
CATransform3DMakeTranslation(tx: CGFloat, ty: CGFloat, tz: CGFloat)
gdzie tx
jest zmianą współrzędnych x, ty
jest zmianą y, a tz
jest zmianą z.
Przykład
W systemie iOS początek układu współrzędnych znajduje się w lewym górnym rogu, więc jeśli chcemy przesunąć warstwę o 90 punktów w prawo i 50 punktów w dół, wykonaj następujące czynności:
myLayer.transform = CATransform3DMakeTranslation(90, 50, 0)
Notatki
- Pamiętaj, że możesz wkleić to do metody
transformExample()
w powyższym kodzie projektu. - Ponieważ mamy tutaj do czynienia z dwoma wymiarami,
tz
jest ustawione na0
. - Czerwona linia na powyższym obrazku biegnie od środka pierwotnej lokalizacji do centrum nowej lokalizacji. Jest tak, ponieważ transformacje są wykonywane w stosunku do punktu kontrolnego, a punkt kontrolny domyślnie znajduje się w środku warstwy.
Skala
Transformacja skali rozciąga lub ściska warstwę. Podstawowa składnia to
CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat)
gdzie sx
, sy
i sz
są liczbami, o które należy skalować (pomnożyć) odpowiednio współrzędne x, y i z.
Przykład
Gdybyśmy chcieli zmniejszyć o połowę szerokość i potroić wysokość, zrobilibyśmy następujące
myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)
Notatki
- Ponieważ pracujemy tylko w dwóch wymiarach, pomnożymy współrzędne z przez 1,0, aby nie uległy zmianie.
- Czerwona kropka na powyższym obrazku oznacza punkt kontrolny. Zauważ, jak skalowanie odbywa się w stosunku do punktu kontrolnego. Oznacza to, że wszystko jest rozciągnięte w kierunku lub od punktu kotwiczenia.
Obracać się
Przekształcenie obrotu powoduje obrócenie warstwy wokół punktu kontrolnego (domyślnie środek warstwy). Podstawowa składnia to
CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat)
gdzie angle
jest kątem w radianach, w którym warstwa powinna zostać obrócona, a x
, y
i z
są osiami, wokół których ma się obracać. Ustawienie osi na 0 anuluje obrót wokół tej konkretnej osi.
Przykład
Gdybyśmy chcieli obrócić warstwę o 30 stopni w prawo, zrobilibyśmy następujące:
let degrees = 30.0
let radians = CGFloat(degrees * M_PI / 180)
myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)
Notatki
- Ponieważ pracujemy w dwóch wymiarach, chcemy, aby płaszczyzna xy była obracana wokół osi Z. Tak więc zestaw
x
iy
do0.0
i są ustawionez
do1.0
. - To obróciło warstwę w kierunku zgodnym z ruchem wskazówek zegara. Moglibyśmy obrócić w lewo, ustawiając
z
na-1.0
. - Czerwona kropka pokazuje, gdzie znajduje się punkt kontrolny. Obrót odbywa się wokół punktu kotwiczenia.
Wiele transformacji
Aby połączyć wiele transformacji, moglibyśmy zastosować taką konkatynację
CATransform3DConcat(a: CATransform3D, b: CATransform3D)
Jednak zrobimy to jeden po drugim. Pierwsza transformacja użyje w nazwie nazwy Make
. Poniższe transformacje nie będą używać Make
, ale przyjmą poprzednią transformację jako parametr.
Przykład
Tym razem łączymy wszystkie trzy poprzednie transformacje.
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
Notatki
- Kolejność, w jakiej transformacje są wykonywane w sprawach.
- Wszystko zostało zrobione w stosunku do punktu kontrolnego (czerwona kropka).
Uwaga na temat punktu i pozycji kotwicy
Wszystkie nasze transformacje wykonaliśmy powyżej bez zmiany punktu kontrolnego. Czasami trzeba go jednak zmienić, na przykład jeśli chcesz obrócić wokół innego punktu poza środkiem. Może to być jednak trochę trudne.
Punkt kotwiczenia i pozycja znajdują się w tym samym miejscu. Punkt kontrolny jest wyrażony jako jednostka układu współrzędnych warstwy (domyślnie 0.5, 0.5
), a pozycja jest wyrażona w układzie współrzędnych warstwy. Można je ustawić w ten sposób
myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
myLayer.position = CGPoint(x: 50, y: 50)
Jeśli ustawisz punkt kontrolny tylko bez zmiany pozycji, wówczas ramka zmieni się, tak że pozycja będzie we właściwym miejscu. Mówiąc dokładniej, rama jest ponownie obliczana na podstawie nowego punktu kotwiczenia i starej pozycji. Zwykle daje to nieoczekiwane wyniki. Dwa poniższe artykuły zawierają doskonałą dyskusję na ten temat.
Zobacz też
Ten przykład pochodzi z tego przykładu przepełnienia stosu .
Wyłącz animacje
Animacje właściwości CALayer
są domyślnie włączone. Gdy jest to niepożądane, można je wyłączyć w następujący sposób.
Szybki
CATransaction.begin()
CATransaction.setDisableActions(true)
// change layer properties that you don't want to animate
CATransaction.commit()
Cel C
[CATransaction begin];
[CATransaction setDisableActions:YES];
// change layer properties that you don't want to animate
[CATransaction commit];
Zaokrąglone rogi
layer.masksToBounds = true;
layer.cornerRadius = 8;
Cienie
Możesz użyć 5 właściwości na każdej warstwie, aby skonfigurować cienie:
-
shadowOffset
- ta właściwość przesuwa twój cień w lewo / prawo lub w górę / w dół
self.layer.shadowOffset = CGSizeMake(-1, -1); // 1px left and up
self.layer.shadowOffset = CGSizeMake(1, 1); // 1px down and right
-
shadowColor
- ustawia kolor twojego cienia
self.layer.shadowColor = [UIColor blackColor].CGColor;
-
shadowOpacity
- jest to krycie cienia, od0
do1
self.layer.shadowOpacity = 0.2;
-
shadowRadius
- jest to promień rozmycia (odpowiednik właściwości rozmycia w Sketch lub Photoshop)
self.layer.shadowRadius = 6;
-
shadowPath
- jest to ważna właściwość dla wydajności, gdy nieuzbrojony iOS opiera cień na kanale alfa widoku, który może być intensywny przy złożonym PNG z alfa. Ta właściwość pozwala wymusić kształt cienia i dzięki temu być bardziej wydajna.
Cel C
self.layer.shadowPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0,0,100,100)]; //this does a circular shadow
Szybki 3
self.layer.shadowPath = UIBezierPath(ovalIn: CGRect(x: 0, y: 0, width: 100, height: 100)).cgPath