將變換新增到 CALayer(平移旋轉刻度)
基本
你可以在一個圖層上執行許多不同的變換,但基本的變換是
- 翻譯(移動)
- 規模
- 迴轉
要在 CALayer
上進行變換,可以將圖層的 transform
屬性設定為 CATransform3D
型別。例如,要翻譯圖層,你可以執行以下操作:
myLayer.transform = CATransform3DMakeTranslation(20, 30, 0)
Make
這個詞在名稱中用於建立初始變換:CATransform3D Make Translation。應用的後續變換省略了 Make
。例如,請參閱此輪換後跟翻譯:
let rotation = CATransform3DMakeRotation(CGFloat(30.0 * M_PI / 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.blueColor().CGColor
myLayer.string = "Hello"
myView.layer.addSublayer(myLayer)
}
//******** Replace this function with the examples below ********
func transformExample() {
// add transform code here ...
}
}
有許多不同種類的 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
。 - 上圖中的紅線從原始位置的中心到新位置的中心。這是因為變換是相對於錨點完成的,預設情況下錨點位於圖層的中心。
規模
縮放變換拉伸或取消該層。基本語法是
CATransform3DMakeScale(sx: CGFloat, sy: CGFloat, sz: CGFloat)
其中 sx
,sy
和 sz
分別是縮放(乘)x,y 和 z 座標的數字。
例
如果我們想要寬度的一半和高度的三倍,我們將執行以下操作
myLayer.transform = CATransform3DMakeScale(0.5, 3.0, 1.0)
筆記
- 由於我們只是在兩個維度上工作,我們只需將 z 座標乘以 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 * M_PI / 180)
myLayer.transform = CATransform3DMakeRotation(radians, 0.0, 0.0, 1.0)
筆記
- 由於我們在兩個維度上工作,我們只希望 xy 平面繞 z 軸旋轉。因此我們將
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 * 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
筆記
- 變換在事務中完成的順序。
- 一切都是關於錨點(紅點)完成的。
關於錨點和位置的註記
我們在不改變錨點的情況下完成了上述所有變換。有時候有必要改變它,就像你想要圍繞中心的其他點旋轉一樣。但是,這可能有點棘手。
錨點和位置都在同一個地方。錨點表示為圖層座標系的單位(預設為 0.5, 0.5
),位置在超層座標系中表示。它們可以像這樣設定
myLayer.anchorPoint = CGPoint(x: 0.0, y: 1.0)
myLayer.position = CGPoint(x: 50, y: 50)
如果僅設定錨點而不更改位置,則框架會發生變化,以使位置位於正確的位置。或者更確切地說,基於新的錨點和舊位置重新計算框架。這通常會產生意外結果。以下兩篇文章對此進行了很好的討論。
也可以看看
此示例最初來自此 Stack Overflow 示例 。