[英]How to do transforms on a CALayer?
Before writing this question, I've 在写这个问题之前,我已经
However, I'm still having trouble understanding how to do basic transforms on a layer . 但是,我仍然无法理解如何在图层上进行基本变换。 Finding explanations and simple examples for translate, rotate and scale has been difficult.
寻找翻译,旋转和缩放的解释和简单示例一直很困难。
Today I finally decided to sit down, make a test project, and figure them out. 今天我终于决定坐下来,做一个测试项目,然后把它们搞清楚。 My answer is below.
我的答案如下。
Notes: 笔记:
There are a number of different transforms you can do on a layer, but the basic ones are 您可以在一个图层上执行许多不同的变换,但基本的变换是
To do transforms on a CALayer
, you set the layer's transform
property to a CATransform3D
type. 要在
CALayer
上执行变换,请将图层的transform
属性设置为CATransform3D
类型。 For example, to translate a layer, you would do something like this: 例如,要翻译图层,您可以执行以下操作:
myLayer.transform = CATransform3DMakeTranslation(20, 30, 0)
The word Make
is used in the name for creating the initial transform: CATransform3D Make Translation. 在创建初始变换的名称中使用单词
Make
:CATransform3D Make Translation。 Subsequent transforms that are applied omit the Make
. 应用的后续转换省略了
Make
。 See, for example, this rotation followed by a translation: 例如,请参阅此轮换后跟翻译:
let rotation = CATransform3DMakeRotation(CGFloat.pi * 30.0 / 180.0, 20, 20, 0)
myLayer.transform = CATransform3DTranslate(rotation, 20, 30, 0)
Now that we have the basis of how to make a transform, let's look at some examples of how to do each one. 既然我们已经有了如何进行变换的基础,那么让我们看看如何做每个变换的一些例子。 First, though, I'll show how I set up the project in case you want to play around with it, too.
首先,我将展示如何设置项目,以防您想要玩它。
For the following examples I set up a Single View Application and added a UIView
with a light blue background to the storyboard. 对于以下示例,我设置了单视图应用程序,并在故事板中添加了浅蓝色背景的
UIView
。 I hooked up the view to the view controller with the following code: 我使用以下代码将视图连接到视图控制器:
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
, but I chose to use CATextLayer
so that the transforms will be more clear visually. 有许多不同种类的
CALayer
,但我选择使用CATextLayer
以便视觉上的变换更加清晰。
The translation transform moves the layer. 平移变换移动图层。 The basic syntax is
基本语法是
CATransform3DMakeTranslation(tx: CGFloat, ty: CGFloat, tz: CGFloat)
where tx
is the change in the x coordinates, ty
is the change in y, and tz
is the change in z. 其中
tx
是x坐标的变化, ty
是y的变化, tz
是z的变化。
Example 例
In iOS the origin of the coordinate system is in the top left, so if we wanted to move the layer 90 points to the right and 50 points down, we would do the following: 在iOS中,坐标系的原点位于左上角,因此如果我们想将图层向右移动90点,向下移动50点,我们将执行以下操作:
myLayer.transform = CATransform3DMakeTranslation(90, 50, 0)
Notes 笔记
transformExample()
method in the project code above. transformExample()
方法中。 tz
is set to 0
. tz
设置为0
。 The scale transform stretches or squishes the layer. 缩放变换拉伸或取消该层。 The basic syntax is
基本语法是
CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat)
where sx
, sy
, and sz
are the numbers by which to scale (multiply) the x, y, and z coordinates respectively. 其中
sx
, sy
和sz
分别是缩放(乘)x,y和z坐标的数字。
Example 例
If we wanted to half the width and triple the height, we would do the following 如果我们想要宽度的一半和高度的三倍,我们将执行以下操作
myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)
Notes 笔记
The rotation transform rotates the layer around the anchor point (the center of the layer by default). 旋转变换围绕锚点旋转图层(默认情况下为图层的中心)。 The basic syntax is
基本语法是
CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat)
where angle
is the angle in radians that the layer should be rotated and x
, y
, and z
are the axes about which to rotate. 其中,
angle
是弧度应该旋转的角度, x
, y
和z
是要旋转的轴。 Setting an axis to 0 cancels a rotation around that particular axis. 将轴设置为0可取消围绕该特定轴的旋转。
Example 例
If we wanted to rotate a layer clockwise 30 degrees, we would do the following: 如果我们想要将图层顺时针旋转30度,我们将执行以下操作:
let degrees = 30.0
let radians = CGFloat(degrees * Double.pi / 180)
myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)
Notes 笔记
x
and y
to 0.0
and set z
to 1.0
. x
和y
设置为0.0
并将z
设置为1.0
。 z
to -1.0
. z
设置为-1.0
来逆时针旋转。 In order to combine multiple transforms we could use concatination like this 为了组合多个变换,我们可以像这样使用concatination
CATransform3DConcat(a: CATransform3D, b: CATransform3D)
However, we will just do one after another. 但是,我们将一个接一个地做。 The first transform will use the
Make
in its name. 第一个转换将使用其名称中的
Make
。 The following transforms will not use Make
, but they will take the previous transform as a parameter. 以下转换不会使用
Make
,但它们会将先前的转换作为参数。
Example 例
This time we combine all three of the previous transforms. 这次我们将前三个变换结合起来。
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
Notes 笔记
We did all our transforms above without changing the anchor point. 我们在不改变锚点的情况下完成了上述所有变换。 Sometimes it is necessary to change it, though, like if you want to rotate around some other point besides the center.
有时候有必要改变它,就像你想要围绕中心以外的其他点旋转一样。 However, this can be a little tricky.
但是,这可能有点棘手。
The anchor point and position are both at the same place. 锚点和位置都在同一个地方。 The anchor point is expressed as a unit of the layer's coordinate system (default is
0.5, 0.5
) and the position is expressed in the superlayer's coordinate system. 锚点表示为层的坐标系统的单元(默认为
0.5, 0.5
)和位置在superlayer的坐标系统中表示。 They can be set like this 它们可以像这样设置
myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
myLayer.position = CGPoint(x: 50, y: 50)
If you only set the anchor point without changing the position, then the frame changes so that the position will be in the right spot. 如果仅设置锚点而不更改位置,则框架会发生变化,以使位置位于正确的位置。 Or more precisely, the frame is recalculated based on the new anchor point and old position.
或者更确切地说,基于新的锚点和旧位置重新计算框架。 This usually gives unexpected results.
这通常会产生意外结果。 The following two articles have an excellent discussion of this.
以下两篇文章对此进行了很好的讨论。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.