之前寫這個問題,我已經如何在CALayer上進行轉換?
- 曾與Affine transforms for views
- 經驗從GitHub
但是,我仍然無法理解如何做一個基本的變換層。尋找翻譯,旋轉和縮放的解釋和簡單例子一直很困難。
今天我終於決定坐下來做一個測試項目,並把它們弄清楚。我的答案如下。
注:
- 我只做斯威夫特,但如果別人要添加的Objective-C代碼,是我的客人。
- 在這一點上,我只關心理解2D變換。
之前寫這個問題,我已經如何在CALayer上進行轉換?
但是,我仍然無法理解如何做一個基本的變換層。尋找翻譯,旋轉和縮放的解釋和簡單例子一直很困難。
今天我終於決定坐下來做一個測試項目,並把它們弄清楚。我的答案如下。
注:
有許多不同的轉換,你可以在層上做的,但基本的有
要對CALayer
執行變換,請將圖層的transform
屬性設置爲CATransform3D
類型。例如,翻譯層,你會做這樣的事情:
myLayer.transform = CATransform3DMakeTranslation(20, 30, 0)
字Make
在名稱中使用創建初始轉換:CATransform3D 讓翻譯。後續應用的轉換省略了Make
。見,例如,這種旋轉再平移:
let rotation = CATransform3DMakeRotation(CGFloat.pi * 30.0/180.0, 20, 20, 0)
myLayer.transform = CATransform3DTranslate(rotation, 20, 30, 0)
現在我們有如何使改造的基礎上,讓我們來看看如何做到每一個的一些例子。不過,首先,我會展示如何設置該項目,以防您也想玩弄它。
設置對於我設置的單一視圖的應用,用淺藍色背景到故事板加入一個UIView
以下實施例。我掛接視圖以用下面的代碼視圖控制器:
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
,但我選擇使用CATextLayer
使得變換會更加清楚視覺。
翻譯變換移動圖層。基本語法是
CATransform3DMakeTranslation(tx: CGFloat, ty: CGFloat, tz: CGFloat)
其中tx
是x座標的變化,ty
是在y中的變化,並且是tz
在z上的變化。
例
在iOS系統中的座標系的原點在左上角,所以如果我們想移動層90點到右側和50分的情況下,我們會做到以下幾點:
myLayer.transform = CATransform3DMakeTranslation(90, 50, 0)
注
transformExample()
方法中。tz
設置爲0
。的尺度變換拉伸或squishes的層。基本語法是
CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat)
其中sx
,sy
,和sz
是數字,通過該按比例繪製(乘)在x,y和z分別座標。
例
如果我們想一半的寬度和三重高度,我們會做以下
myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)
注
旋轉變換繞錨點的層(該層的默認的中心)。基本語法是
CATransform3DMakeRotation(angle: CGFloat, x: CGFloat, y: CGFloat, z: CGFloat)
其中angle
是弧度的角度,該層應該旋轉和x
,y
,和z
是圍繞其旋轉的軸。將座標軸設置爲0將取消圍繞該特定軸的旋轉。
例
如果我們想層順時針旋轉30度,我們將做到以下幾點:
let degrees = 30.0
let radians = CGFloat(degrees * Double.pi/180)
myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)
注
x
和y
設置爲0.0
並將z
設置爲1.0
。z
設置爲-1.0
來逆時針旋轉。爲了多變換結合,我們可以使用concatination這樣
CATransform3DConcat(a: CATransform3D, b: CATransform3D)
不過,我們會只是做了一個又一個。第一個轉換將使用其名稱中的Make
。以下轉換不會使用Make
,但它們將以前一個轉換爲參數。
例
這一次,我們結合這三個以前的變換。
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
注
我們盡了所有變換上述不改變錨點。有時候有必要改變它,但是,如果你想圍繞中心以外的其他點旋轉。但是,這可能有點棘手。
定位點和位置都在同一個地方。定位點表示爲圖層座標系統的一個單位(默認值爲0.5, 0.5
),位置用超級座標系統表示。它們可以這樣設置
myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
myLayer.position = CGPoint(x: 50, y: 50)
如果只設置錨點而不改變位置,然後在框架的變化,使得位置將是在正確的位置。或者更準確地說,根據新的錨點和舊的位置重新計算框架。這通常會帶來意想不到的結以下兩篇文章對此進行了精彩的討論。