將變換新增到 CALayer(平移旋轉刻度)

基本

你可以在一個圖層上執行許多不同的變換,但基本的變換是

  • 翻譯(移動)
  • 規模
  • 迴轉

StackOverflow 文件

要在 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 的變化。

StackOverflow 文件

在 iOS 中,座標系的原點位於左上角,因此如果我們想將圖層向右移動 90 點並向下移動 50 點,我們將執行以下操作:

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

筆記

  • 請記住,你可以將其貼上到上面專案程式碼中的 transformExample() 方法中。
  • 由於我們將在這裡處理兩個維度,tz 將設定為 0
  • 上圖中的紅線從原始位置的中心到新位置的中心。這是因為變換是相對於錨點完成的,預設情況下錨點位於圖層的中心。

規模

縮放變換拉伸或取消該層。基本語法是

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

其中 sxsysz 分別是縮放(乘)x,y 和 z 座標的數字。

StackOverflow 文件

如果我們想要寬度的一半和高度的三倍,我們將執行以下操作

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

筆記

  • 由於我們只是在兩個維度上工作,我們只需將 z 座標乘以 1.0 即可使它們不受影響。
  • 上圖中的紅點表示錨點。注意如何相對於錨點完成縮放。也就是說,一切都朝向或遠離錨點拉伸。

旋轉

旋轉變換圍繞錨點旋轉圖層(預設情況下為圖層的中心)。基本語法是

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

其中 angle 是弧應該旋轉的角度,xyz 是旋轉的軸。將軸設定為 0 可取消圍繞該特定軸的旋轉。

StackOverflow 文件

如果我們想要將圖層順時針旋轉 30 度,我們將執行以下操作:

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

筆記

  • 由於我們在兩個維度上工作,我們只希望 xy 平面繞 z 軸旋轉。因此我們將 xy 設定為 0.0 並將 z 設定為 1.0
  • 這使圖層順時針旋轉。我們可以通過將 z 設定為 -1.0 來逆時針旋轉。
  • 紅點顯示錨點的位置。圍繞錨點完成旋轉。

多次轉換

為了組合多個變換,我們可以像這樣使用 concatination

CATransform3DConcat(a: CATransform3D, b: CATransform3D)

但是,我們將一個接一個地做。第一個轉換將在其名稱中使用 Make。以下變換不會使用 Make,但它們會將先前的變換作為引數。

StackOverflow 文件

這次我們將前三個變換結合起來。

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 示例