簡體   English   中英

iPhone 旋轉時 CALayer 的自動旋轉

[英]Autorotation of CALayer on iPhone rotation

我有一個 UIViewController,我在其中向視圖層添加了 CALayer 子類:

[self.view.layer addSublayer:myObject.backgroundLayer];

當我旋轉設備時,視圖會旋轉,但 CALayer 不會。 它有點被分流到左邊,仍然是縱向視圖。

有沒有辦法讓子圖層自動旋轉,或者我需要應用變換嗎?

使用 Swift 4 / iOS 11,根據您的需要,您可以選擇以下 6 個示例之一,以便在設備旋轉時管理您的CALayer / CAGradientLayer框架。

下面的示例使用CAGradientLayer但可以輕松映射到CALayerCAShapeLayer案例。


#1. 覆蓋UIViewController viewDidLayoutSubviews()

import UIKit

class ViewController: UIViewController {

    let gradientLayer: CAGradientLayer = {
        let layer = CAGradientLayer()
        layer.colors = [
            UIColor.blue.cgColor,
            UIColor.cyan.cgColor
        ]
        return layer
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.layer.addSublayer(gradientLayer)
        gradientLayer.frame = view.bounds
    }

    override func viewDidLayoutSubviews() {         
        gradientLayer.frame = view.bounds
    }

}

#2. 覆蓋UIViewController loadView()UIView和覆蓋UIView layoutSubviews()

圖層視圖.swift

import UIKit

class LayerView: UIView {

    lazy var gradientLayer: CAGradientLayer = {
        let layer = CAGradientLayer()
        layer.colors = [
            UIColor.blue.cgColor,
            UIColor.cyan.cgColor
        ]
        self.layer.addSublayer(layer)
        return layer
    }()

    override func layoutSubviews() {
        gradientLayer.frame = bounds
    }

}

LayerView.swift(替代)

import UIKit

class LayerView: UIView {

    var gradientLayer: CAGradientLayer!

    override func layoutSubviews() {
        if gradientLayer == nil {
            let gradientLayer = CAGradientLayer()
            gradientLayer.colors = [
                UIColor.blue.cgColor,
                UIColor.cyan.cgColor
            ]
            self.gradientLayer = gradientLayer
            layer.addSublayer(gradientLayer)
        }

        gradientLayer.frame = bounds
    }

}

視圖控制器.swift

import UIKit

class ViewController: UIViewController {

    let layerView = LayerView()

    override func loadView() {
        view = layerView
    }

}

#3. 使用鍵值觀察 (KVO)

import UIKit

class ViewController: UIViewController {

    var observation: NSKeyValueObservation?

    let gradientLayer: CAGradientLayer = {
        let layer = CAGradientLayer()
        layer.colors = [
            UIColor.blue.cgColor,
            UIColor.cyan.cgColor
        ]
        return layer
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.layer.addSublayer(gradientLayer)

        observation = view.observe(\.frame, options: [.new], changeHandler: { [unowned self] (object: UIView, change: NSKeyValueObservedChange<CGRect>) in
            guard let frame = change.newValue else { return }
            self.gradientLayer.frame = frame
        })

        // Also works
        /*
        observation = observe(\.view.frame, options: [.new], changeHandler: { [unowned self] (object: ViewController, change: NSKeyValueObservedChange<CGRect>) in
            guard let frame = change.newValue else { return }
            self.gradientLayer.frame = frame
        })
        */
    }

}

#4. 覆蓋UIViewController loadView()layerClass UIView和覆蓋UIView layerClass

圖層視圖.swift

import UIKit

class LayerView: UIView {

    override public class var layerClass: AnyClass {
        return CAGradientLayer.self
    }

    required init() {
        super.init(frame: .zero)

        guard let gradientLayer = layer as? CAGradientLayer else { return }
        gradientLayer.colors = [
            UIColor.blue.cgColor,
            UIColor.cyan.cgColor
        ]
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

}

視圖控制器.swift

import UIKit

class ViewController: UIViewController {

    let layerView = LayerView()

    override func loadView() {
        view = layerView
    }

}

#5. 覆蓋UIViewController loadView()CALayerDelegate UIView和覆蓋CALayerDelegate layoutSublayers(of:)

圖層視圖.swift

import UIKit

class LayerView: UIView {

    required init() {
        super.init(frame: .zero)

        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = [
            UIColor.blue.cgColor,
            UIColor.cyan.cgColor
        ]

        layer.addSublayer(gradientLayer)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSublayers(of layer: CALayer) {
        layer.sublayers?.forEach {
            $0.frame = layer.bounds
        }
    }

}

視圖控制器.swift

import UIKit

class ViewController: UIViewController {

    let layerView = LayerView()

    override func loadView() {
        view = layerView
    }

}

#6. 覆蓋UIViewController loadView() ,子類化UIView ,覆蓋UIView layerClass ,子類化CALayer和覆蓋CALayer layoutSublayers()

層.swift

import UIKit

class Layer: CALayer {

    override init() {
        super.init()

        let gradientLayer = CAGradientLayer()
        gradientLayer.colors = [
            UIColor.blue.cgColor,
            UIColor.cyan.cgColor
        ]

        addSublayer(gradientLayer)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func layoutSublayers() {
        sublayers?.forEach {
            $0.frame = bounds
        }
    }

}

圖層視圖.swift

import UIKit

class LayerView: UIView {

    override public class var layerClass: AnyClass {
        return Layer.self
    }

}

視圖控制器.swift

import UIKit

class ViewController: UIViewController {

    let layerView = LayerView()

    override func loadView() {
        view = layerView
    }

}

資料來源:

您需要自己管理 CALayer 的旋轉。 我相信 0,0 保持在同一個位置,並且大小會改變以匹配新的方向,所以如果你想自己做一些事情,你需要自己管理旋轉變換的添加。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM