iOS Ajout de transformations à un calayer (traduction, rotation, mise à l'échelle)


Exemple

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

Transformations de base

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)

tx est le changement des coordonnées x, ty est le changement de y et tz est le changement de z.

Exemple

traduire 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 sur 0 .
  • 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)

sx , sy et sz sont les nombres par lesquels mettre à l'échelle (multiplier) respectivement les coordonnées x, y et z.

Exemple

exemple d'échelle

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)

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

faire pivoter l'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 et y à 0.0 et définissons z à 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

exemple de transformations multiples

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

Cet exemple provient à l'origine de cet exemple de débordement de pile .