Recherche…
Créer un calayer
Vous pouvez créer un calayer et définir son cadre comme suit:
Rapide:
let layer = CALayer()
layer.frame = CGRect(x: 0, y: 0, width: 60, height: 80)
Objectif c:
CALayer *layer = [[CALayer alloc] init];
layer.frame = CGRectMake(0, 0, 60, 80);
Vous pouvez ensuite l'ajouter en tant que sous-couche à un CALayer existant:
Rapide:
existingLayer.addSublayer(layer)
Objectif c:
[existingLayer addSublayer:layer];
Remarque:
Pour ce faire, vous devez inclure le framework QuartzCore.
Rapide:
@import QuartzCore
Objectif c
#import <QuartzCore/QuartzCore.h>
Création de particules avec CAEmitterLayer
La classe CAEmitterLayer fournit un système émetteur de particules pour Core Animation. Les particules sont définies par des instances de CAEmitterCell .
Les particules sont dessinées au-dessus de la couleur d'arrière-plan et de la bordure du calque.
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 avec une image personnalisée
Par exemple, nous allons créer une vue contenant une couche d'émetteur et animer des particules.
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
}
}
Vous devez ajouter une image "confetti" ou définir rect avec confetti.contentsRect
Comment ajouter un UIImage à un CALayer
Vous pouvez ajouter une image au layer
une vue en utilisant simplement sa propriété de contents
:
myView.layer.contents = UIImage(named: "star")?.CGImage
- Notez que l'
UIImage
doit être converti en unCGImage
.
Si vous souhaitez ajouter l'image dans son propre calque, vous pouvez le faire comme ceci:
let myLayer = CALayer()
let myImage = UIImage(named: "star")?.CGImage
myLayer.frame = myView.bounds
myLayer.contents = myImage
myView.layer.addSublayer(myLayer)
Modifier l'apparence
Le code ci-dessus produit une vue comme celle-ci. Le bleu clair est l' UIView
et l'étoile bleu foncé est l' UIImage
.
Comme vous pouvez le voir, cependant, il semble pixélisé. Ceci est dû au fait que UIImage
est plus petit que UIView
, il est donc mis à l'échelle pour remplir la vue, ce qui est la valeur par défaut que vous ne spécifiez pas.
Les exemples ci-dessous présentent des variantes sur la propriété de contentsGravity
du calque. Le code ressemble à ceci:
myView.layer.contents = UIImage(named: "star")?.CGImage
myView.layer.contentsGravity = kCAGravityTop
myView.layer.geometryFlipped = true
Dans iOS, vous souhaiterez peut-être définir la propriété geometryFlipped
sur true
si vous faites quelque chose avec la gravité supérieure ou inférieure, sinon ce sera le contraire de ce que vous attendez. (Seule la gravité est retournée verticalement, pas le rendu du contenu. Si vous rencontrez des problèmes avec le contenu retourné, consultez cette réponse Stack Overflow .)
Il y a deux exemples UIView
ci-dessous pour chaque contentsGravity
Réglage de la UIImage
, une vue est plus grande que l' UIImage
et l'autre est plus petite. De cette façon, vous pouvez voir les effets de la mise à l'échelle et de la gravité.
kCAGravityResize
Ceci est la valeur par défaut.
kCAGravityResizeAspect
kCAGravityResizeAspectFill
kCAGravityCenter
kCAGravityTop
kCAGravityBottom
kCAGravityLeft
kCAGravityRight
kCAGravityTopLeft
kCAGravityTopRight
kCAGravityBottomLeft
kCAGravityBottomRight
en relation
- Propriété du mode contenu d'une vue
- Dessiner un
UIImage
dansdrawRect
avecCGContextDrawImage
- Tutoriel CALayer: Mise en route
Remarques
- Cet exemple provient de cette réponse Stack Overflow .
Ajout de transformations à un calayer (traduction, rotation, mise à l'échelle)
Les bases
Il y a un certain nombre de transformations différentes que vous pouvez faire sur une couche, mais les bases sont
- traduire (déplacer)
- échelle
- tourner
Pour effectuer des transformations sur un CALayer
, définissez la propriété transform
la couche sur un type CATransform3D
. Par exemple, pour traduire un calque, vous feriez quelque chose comme ceci:
myLayer.transform = CATransform3DMakeTranslation(20, 30, 0)
Le mot Make
est utilisé dans le nom pour créer la transformation initiale: CATransform3D Make Translation. Les transformations ultérieures qui sont appliquées omettent le Make
. Voir, par exemple, cette rotation suivie d'une traduction:
let rotation = CATransform3DMakeRotation(CGFloat(30.0 * M_PI / 180.0), 20, 20, 0)
myLayer.transform = CATransform3DTranslate(rotation, 20, 30, 0)
Maintenant que nous avons la base de la manière de transformer, examinons quelques exemples de la façon de procéder. D'abord, cependant, je montrerai comment j'ai configuré le projet au cas où vous voudriez y jouer.
Installer
Pour les exemples suivants, j'ai configuré une application à UIView
unique et ajouté un UIView
avec un arrière-plan bleu clair au storyboard. J'ai branché la vue au contrôleur de vue avec le code suivant:
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 ...
}
}
Il existe de nombreux types de CALayer
, mais j'ai choisi d'utiliser CATextLayer
pour que les transformations soient plus claires visuellement.
Traduire
La transformation de traduction déplace le calque. La syntaxe de base est
CATransform3DMakeTranslation(tx: CGFloat, ty: CGFloat, tz: CGFloat)
où tx
est le changement des coordonnées x, ty
est le changement de y et tz
est le changement de z.
Exemple
Dans iOS, l'origine du système de coordonnées est en haut à gauche, donc si nous voulions déplacer la couche de 90 points vers la droite et de 50 points vers le bas, nous procéderions comme suit:
myLayer.transform = CATransform3DMakeTranslation(90, 50, 0)
Remarques
- N'oubliez pas que vous pouvez le coller dans la méthode
transformExample()
du code du projet ci-dessus. - Puisque nous ne faisons que traiter de deux dimensions,
tz
est défini sur0
. - La ligne rouge dans l'image ci-dessus va du centre de l'emplacement d'origine au centre du nouvel emplacement. En effet, les transformations sont effectuées par rapport au point d'ancrage et le point d'ancrage par défaut au centre du calque.
Échelle
La transformation d'échelle étend ou écrase le calque. La syntaxe de base est
CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat)
où sx
, sy
et sz
sont les nombres par lesquels mettre à l'échelle (multiplier) respectivement les coordonnées x, y et z.
Exemple
Si nous voulions réduire de moitié la largeur et tripler la hauteur, nous ferions ce qui suit
myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)
Remarques
- Comme nous ne travaillons que dans deux dimensions, nous multiplions simplement les coordonnées z par 1,0 pour ne pas les affecter.
- Le point rouge dans l'image ci-dessus représente le point d'ancrage. Remarquez comment la mise à l'échelle est effectuée par rapport au point d'ancrage. C'est-à-dire que tout est soit tendu vers ou loin du point d'ancrage.
Tourner
La transformation de rotation fait pivoter le calque autour du point d'ancrage (le centre du calque par défaut). La syntaxe de base est
CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat)
où angle
est l'angle en radians avec lequel le calque doit être pivoté et x
, y
et z
sont les axes autour desquels faire pivoter. Définir un axe sur 0 annule une rotation autour de cet axe particulier.
Exemple
Si nous voulions tourner une couche de 30 degrés dans le sens des aiguilles d'une montre, nous ferions ce qui suit:
let degrees = 30.0
let radians = CGFloat(degrees * M_PI / 180)
myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)
Remarques
- Puisque nous travaillons en deux dimensions, nous voulons seulement que le plan xy soit pivoté autour de l'axe z. Nous définissons donc
x
ety
à0.0
et définissonsz
à1.0
. - Cela a fait pivoter la couche dans le sens des aiguilles d'une montre. Nous aurions pu tourner dans le sens inverse des aiguilles d'une montre en définissant
z
sur-1.0
. - Le point rouge indique où se trouve le point d'ancrage. La rotation se fait autour du point d'ancrage.
Transformations multiples
Afin de combiner plusieurs transformations, nous pourrions utiliser la concatination comme ceci
CATransform3DConcat(a: CATransform3D, b: CATransform3D)
Cependant, nous ne ferons que l'un après l'autre. La première transformation utilisera le Make
dans son nom. Les transformations suivantes n'utiliseront pas Make
, mais elles prendront la transformation précédente en tant que paramètre.
Exemple
Cette fois, nous combinons les trois transformations précédentes.
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
Remarques
- L'ordre dans lequel les transformations se font dans les matières.
- Tout a été fait par rapport au point d'ancrage (point rouge).
Une remarque sur le point d'ancrage et la position
Nous avons fait toutes nos transformations ci-dessus sans changer le point d'ancrage. Parfois, il est nécessaire de le changer, par exemple si vous souhaitez effectuer une rotation autour d'un autre point que le centre. Cependant, cela peut être un peu difficile.
Le point d'ancrage et la position sont tous deux au même endroit. Le point d'ancrage est exprimé comme une unité du système de coordonnées de la couche (la valeur par défaut est 0.5, 0.5
) et la position est exprimée dans le système de coordonnées de la super-couche. Ils peuvent être mis comme ça
myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
myLayer.position = CGPoint(x: 50, y: 50)
Si vous définissez uniquement le point d'ancrage sans modifier la position, le cadre change pour que la position soit au bon endroit. Ou plus précisément, la trame est recalculée en fonction du nouveau point d'ancrage et de l'ancienne position. Cela donne généralement des résultats inattendus. Les deux articles suivants ont une excellente discussion à ce sujet.
Voir également
- Bordure, coins arrondis et ombre sur un
CALayer
- Utiliser une bordure avec un chemin de Bézier pour un calque
Cet exemple provient à l'origine de cet exemple de débordement de pile .
Désactiver les animations
CALayer
animations de propriétés CALayer
sont activées par défaut. Lorsque cela est indésirable, ils peuvent être désactivés comme suit.
Rapide
CATransaction.begin()
CATransaction.setDisableActions(true)
// change layer properties that you don't want to animate
CATransaction.commit()
Objectif c
[CATransaction begin];
[CATransaction setDisableActions:YES];
// change layer properties that you don't want to animate
[CATransaction commit];
Coins arrondis
layer.masksToBounds = true;
layer.cornerRadius = 8;
Ombres
Vous pouvez utiliser 5 propriétés sur chaque couche pour configurer vos ombres:
-
shadowOffset
- cette propriété déplace votre ombre gauche / droite ou haut / bas
self.layer.shadowOffset = CGSizeMake(-1, -1); // 1px left and up
self.layer.shadowOffset = CGSizeMake(1, 1); // 1px down and right
-
shadowColor
- définit la couleur de votre ombre
self.layer.shadowColor = [UIColor blackColor].CGColor;
-
shadowOpacity
- c'est l'opacité de l'ombre, de0
à1
self.layer.shadowOpacity = 0.2;
-
shadowRadius
- c'est le rayon de flou (équivalent de la propriété de flou dans Sketch ou Photoshop)
self.layer.shadowRadius = 6;
-
shadowPath
- il s'agit d'une propriété importante pour les performances, lorsque iOS non défini fonde l'ombre sur le canal alpha de la vue, ce qui peut nécessiter de nombreuses performances avec un format PNG complexe avec alpha. Cette propriété vous permet de forcer une forme pour votre ombre et d'être plus performant grâce à cela.
Objectif 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