在iPhone轮换上自动旋转CALayer

我有一个UIViewController,我将CALayer子类添加到视图的层:

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

当我旋转设备时,视图会旋转,但CALayer不会旋转。 它有点被分流到左边,仍然是纵向视图。

有没有办法让子图层自动旋转或者我是否需要应用变换?

您需要自己管理CALayer的轮换。 我相信0,0会停留在同一个地方并且大小会改变以匹配新的方向,所以如果你想自己做一些事情,你需要自己管理添加旋转变换。

使用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()

LayerView.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 } } 

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

#4。 覆盖UIViewController loadView() ,子类化UIView并覆盖UIView layerClass

LayerView.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") } } 

ViewController.swift

 import UIKit class ViewController: UIViewController { let layerView = LayerView() override func loadView() { view = layerView } } 

#5。 覆盖UIViewController loadView() ,子类化UIView并覆盖CALayerDelegate layoutSublayers(of:)

LayerView.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 } } } 

ViewController.swift

 import UIKit class ViewController: UIViewController { let layerView = LayerView() override func loadView() { view = layerView } } 

#6。 覆盖UIViewController loadView() ,子类化UIView ,重写UIView layerClass ,子类化CALayer并覆盖CALayer layoutSublayers()

Layer.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 } } } 

LayerView.swift

 import UIKit class LayerView: UIView { override public class var layerClass: AnyClass { return Layer.self } } 

ViewController.swift

 import UIKit class ViewController: UIViewController { let layerView = LayerView() override func loadView() { view = layerView } } 

资料来源:

  • medium.com
  • github.com
  • developer.apple.com