iOS Aggiungere trasformazioni a un CALayer (tradurre, ruotare, ridimensionare)


Esempio

Nozioni di base

Ci sono un certo numero di trasformazioni diverse che puoi fare su un livello, ma quelle di base sono

  • tradurre (spostare)
  • scala
  • ruotare

trasformazioni di base

Per eseguire trasformazioni su un CALayer , impostare la proprietà di transform del livello su un tipo CATransform3D . Ad esempio, per tradurre un livello, si dovrebbe fare qualcosa del genere:

myLayer.transform = CATransform3DMakeTranslation(20, 30, 0)

La parola Make è usata nel nome per creare la trasformazione iniziale: CATransform3D Make Translation. Le trasformazioni successive che vengono applicate omettono il Make . Vedi, per esempio, questa rotazione seguita da una traduzione:

let rotation = CATransform3DMakeRotation(CGFloat(30.0 * M_PI / 180.0), 20, 20, 0)
myLayer.transform = CATransform3DTranslate(rotation, 20, 30, 0)

Ora che abbiamo le basi su come realizzare una trasformazione, diamo un'occhiata ad alcuni esempi su come fare ognuno di essi. Prima, però, mostrerò come ho impostato il progetto nel caso in cui vogliate giocare con esso.

Impostare

Per gli esempi che seguono ho impostato un'applicazione di visualizzazione singola e aggiunto uno UIView con uno sfondo blu chiaro allo storyboard. Ho collegato la vista al controller della vista con il seguente codice:

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 ...
        
        
    }

} 

Esistono molti tipi diversi di CALayer , ma ho scelto di utilizzare CATextLayer modo che le trasformazioni siano visivamente più chiare.

Tradurre

La trasformazione di traduzione sposta il livello. La sintassi di base è

CATransform3DMakeTranslation(tx: CGFloat, ty: CGFloat, tz: CGFloat)

dove tx è il cambiamento nelle coordinate x, ty è il cambiamento in y, e tz è il cambiamento in z.

Esempio

traduci esempio

In iOS l'origine del sistema di coordinate è in alto a sinistra, quindi se volessimo spostare il livello di 90 punti verso destra e 50 punti verso il basso, faremo quanto segue:

myLayer.transform = CATransform3DMakeTranslation(90, 50, 0)

Gli appunti

  • Ricorda che puoi incollarlo nel metodo transformExample() nel codice progetto precedente.
  • Dato che stiamo andando a trattare due dimensioni qui, tz è impostato a 0 .
  • La linea rossa nell'immagine qui sopra va dal centro della posizione originale al centro della nuova posizione. Questo perché le trasformazioni vengono eseguite in relazione al punto di ancoraggio e il punto di ancoraggio di default si trova al centro del livello.

Scala

La scala trasforma tratti o schiaccia il livello. La sintassi di base è

CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat)

dove sx , sy e sz sono i numeri con cui ridimensionare (moltiplicare) le coordinate x, y e z rispettivamente.

Esempio

esempio di scala

Se volessimo metà della larghezza e triplicare l'altezza, faremmo quanto segue

myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)

Gli appunti

  • Dato che stiamo lavorando solo in due dimensioni, moltiplichiamo le coordinate z per 1.0 per lasciarle inalterate.
  • Il punto rosso nell'immagine sopra rappresenta il punto di ancoraggio. Nota come il ridimensionamento è fatto in relazione al punto di ancoraggio. Cioè, tutto è teso verso o lontano dal punto di ancoraggio.

Ruotare

La trasformazione di rotazione ruota lo strato attorno al punto di ancoraggio (il centro del livello di default). La sintassi di base è

CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat)

dove angle è l'angolo in radianti che lo strato deve essere ruotato e x , y e z sono gli assi su cui ruotare. Impostando un asse su 0 si annulla una rotazione attorno a quel particolare asse.

Esempio

ruotare l'esempio

Se volessimo ruotare uno strato in senso orario di 30 gradi, faremmo quanto segue:

let degrees = 30.0
let radians = CGFloat(degrees * M_PI / 180)
myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)

Gli appunti

  • Dato che stiamo lavorando in due dimensioni, vogliamo solo che il piano xy sia ruotato attorno all'asse z. Così abbiamo impostato x ed y di 0.0 e impostare z a 1.0 .
  • Questo ha ruotato lo strato in senso orario. Potremmo aver ruotato in senso antiorario impostando z su -1.0 .
  • Il punto rosso indica dove si trova il punto di ancoraggio. La rotazione viene eseguita attorno al punto di ancoraggio.

Trasformazioni multiple

Per combinare più trasformazioni, potremmo usare la concatinazione come questa

CATransform3DConcat(a: CATransform3D, b: CATransform3D)

Tuttavia, faremo solo uno dopo l'altro. La prima trasformazione utilizzerà la Make nel suo nome. Le seguenti trasformazioni non useranno Make , ma prenderanno la trasformazione precedente come parametro.

Esempio

esempio di molte trasformazioni

Questa volta combiniamo tutte e tre le trasformazioni precedenti.

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

Gli appunti

  • L'ordine in cui le trasformazioni sono fatte in materia.
  • Tutto è stato fatto in relazione al punto di ancoraggio (punto rosso).

Una nota su punto di ancoraggio e posizione

Abbiamo fatto tutte le nostre trasformazioni sopra senza cambiare il punto di ancoraggio. A volte è necessario cambiarlo, però, come se si volesse ruotare attorno ad un altro punto oltre al centro. Tuttavia, questo può essere un po 'complicato.

Il punto di ancoraggio e la posizione sono entrambi nello stesso punto. Il punto di ancoraggio è espresso come unità del sistema di coordinate del livello (il valore predefinito è 0.5, 0.5 ) e la posizione è espressa nel sistema di coordinate del superlayer. Possono essere impostati in questo modo

myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
myLayer.position = CGPoint(x: 50, y: 50)

Se si imposta solo il punto di ancoraggio senza modificare la posizione, la cornice cambia in modo tale che la posizione si trovi nel punto giusto. O più precisamente, la cornice viene ricalcolata in base al nuovo punto di ancoraggio e alla vecchia posizione. Questo di solito dà risultati inaspettati. I seguenti due articoli hanno un'ottima discussione su questo.

Guarda anche

Questo esempio deriva originariamente da questo esempio di overflow dello stack .