2015-12-23 9 views
13

Bevor diese Frage zu schreiben, habe ichWie transformiert man einen CALayer?

lesen

Allerdings habe ich immer noch Probleme zu verstehen, wie grundlegende Transformationen auf einem zu tun Schicht. Es war schwierig, Erklärungen und einfache Beispiele zum Übersetzen, Drehen und Skalieren zu finden.

Heute habe ich mich endlich dazu entschieden, mich hinzusetzen, ein Testprojekt zu machen und sie herauszufinden. Meine Antwort ist unten.

Hinweise:

  • ich nur Swift, aber wenn jemand anderes will den Objective-C-Code hinzufügen, meinen Gast.
  • An diesem Punkt bin ich nur mit 2D-Transformationen zu verstehen.

Antwort

51

Basics

Es gibt eine Reihe von verschiedenen verwandelt Sie auf einer Ebene tun können, aber die grundlegenden diejenigen sind

  • übersetzen (move)
  • Skala
  • drehen

enter image description here

Um Transformationen für CALayer durchzuführen, legen Sie die transform-Eigenschaft des Layers auf CATransform3D fest. Um zum Beispiel eine Schicht zu übersetzen, würden Sie so etwas tun:

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

Das Wort Make wird im Namen verwendet für die Erstellung der anfänglichen Transformation: CATransform3D Übersetzung machen. Nachfolgende Transformationen, die angewendet werden, lassen die Make aus. Siehe zum Beispiel, diese Drehung durch eine Übersetzung gefolgt:

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

Jetzt, da wir die Grundlage dafür, wie eine Transformation zu machen, lassen Sie uns einen Blick auf einige Beispiele dafür, wie jedes zu tun. Zuerst werde ich aber zeigen, wie ich das Projekt aufsetze, falls du auch damit spielen willst.

Setup-

Für die folgenden Beispiele ich eine Single View Anwendung einrichten und ein UIView mit einem hellblauen Hintergrund zum Storyboard hinzugefügt.Ich hakte den Blick auf die View-Controller mit dem folgenden Code auf:

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.blue.cgColor 
     myLayer.string = "Hello" 
     myView.layer.addSublayer(myLayer) 
    } 

    //******** Replace this function with the examples below ******** 

    func transformExample() { 

     // add transform code here ... 


    } 

} 

There are many different kinds of CALayer, aber ich wählte CATextLayer, so dass die Transformationen optisch klar sein werden, zu verwenden.

Übersetzen

Die Translationstransformation bewegt die Ebene. Die grundlegende Syntax ist

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

wo tx ist die Änderung in den x-Koordinaten, ty die Änderung in y ist, und tz ist die Änderung in z.

Beispiel

enter image description here

In iOS der Ursprung des Koordinatensystems in der oberen linken, also, wenn wir die Schicht 90 Punkte auf der rechten Seite und 50 Punkte nach unten würde, sich bewegen wollten wir wie folgt vor:

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

Hinweise

  • Denken Sie daran, dass Sie dies in die Methode transformExample() im obigen Projektcode einfügen können.
  • Da wir hier nur zwei Dimensionen behandeln, wird tz auf 0 gesetzt.
  • Die rote Linie im Bild oben geht von der Mitte der ursprünglichen Position zur Mitte der neuen Position. Das liegt daran, dass Transformationen in Bezug auf den Ankerpunkt ausgeführt werden und der Ankerpunkt standardmäßig in der Mitte der Ebene liegt.

Maßstab

Die Skala erstreckt Transformation oder die Schicht zerquetscht. Die grundlegende Syntax ist

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

wo sx, sy und sz sind die Zahlen, mit denen (multiplizieren) maßstäblich die x, y und z jeweils koordiniert.

Beispiel

enter image description here

Wenn wir die Hälfte der Breite und die dreifache Höhe wollten, würden wir folgende

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

Notizen machen

  • Da wir nur in zwei Dimensionen arbeiten, Wir multiplizieren einfach die z-Koordinaten mit 1.0, um sie unberührt zu lassen.
  • Der rote Punkt im Bild zeigt den Ankerpunkt. Beachten Sie, wie die Skalierung in Bezug auf den Ankerpunkt erfolgt. Das heißt, alles ist entweder auf den Ankerpunkt zu oder von ihm weg gestreckt.

Rotate

Die Rotationstransformation dreht die Schicht um den Ankerpunkt (das Zentrum der Schicht Standard). Die grundlegende Syntax ist

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

wo angle der Winkel im Bogenmaß ist, dass die Schicht gedreht werden sollte, und x, y und z sind die Achsen, um die sich zu drehen. Wenn Sie eine Achse auf 0 setzen, wird eine Drehung um diese bestimmte Achse aufgehoben.

Beispiel

enter image description here

Wenn wir eine Schicht im Uhrzeigersinn 30 Grad drehen wollten, würden wir die folgenden:

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

Hinweise

  • Da wir Wir arbeiten nur in zwei Dimensionen die xy-Ebene wird um die z-Achse gedreht. Somit setzen wir x und y auf 0.0 und setzen z auf 1.0.
  • Dies drehte die Schicht im Uhrzeigersinn. Wir hätten gegen den Uhrzeigersinn drehen können, indem wir z auf -1.0 setzen.
  • Der rote Punkt zeigt an, wo der Ankerpunkt ist. Die Rotation erfolgt um den Ankerpunkt.

Multiple

Um wandelt mehrere Transformationen kombinieren wir Verketten wie diese

CATransform3DConcat(a: CATransform3D, b: CATransform3D) 

Allerdings nutzen könnten, werden wir tun, nur einen nach dem anderen. Die erste Transformation wird Make in ihrem Namen verwenden. Die folgenden Transformationen verwenden Make nicht, aber sie verwenden die vorherige Transformation als Parameter.

Beispiel

enter image description here

Dieses Mal haben wir alle drei der vorherigen Transformationen kombinieren.

let degrees = 30.0 
let radians = CGFloat(degrees * Double.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 

Hinweise

  • Die Reihenfolge, dass die Transformationen in Sachen fertig sind.
  • Alles wurde in Bezug auf den Ankerpunkt (roter Punkt) gemacht.

Ein Hinweis zu Anchor Point und Position

Wir haben alle unsere Transformationen oben ohne den Ankerpunkt zu ändern.Manchmal ist es notwendig, sie zu ändern, als ob Sie sich um einen anderen Punkt neben dem Zentrum drehen möchten. Dies kann jedoch ein wenig schwierig sein.

Der Ankerpunkt und die Position sind beide an der gleichen Stelle. Der Ankerpunkt wird als Einheit des Koordinatensystems der Ebene ausgedrückt (Standard ist 0.5, 0.5) und die Position wird im Koordinatensystem des Superlayers ausgedrückt. Sie können wie diese

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

gesetzt werden, wenn Sie nur den Ankerpunkt gesetzt, ohne die Position zu ändern, dann der Rahmen ändern, so dass die Position an der richtigen Stelle sein. Genauer gesagt wird der Rahmen 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