在iPhone轮换上自动旋转CALayer
我有一个UIViewController,我将CALayer子类添加到视图的层:
[self.view.layer addSublayer:myObject.backgroundLayer];
当我旋转设备时,视图会旋转,但CALayer不会旋转。 它有点被分流到左边,仍然是纵向视图。
有没有办法让子图层自动旋转或者我是否需要应用变换?
您需要自己管理CALayer的轮换。 我相信0,0会停留在同一个地方并且大小会改变以匹配新的方向,所以如果你想自己做一些事情,你需要自己管理添加旋转变换。
使用Swift 4 / iOS 11,根据您的需要,您可以选择以下6个示例中的一个,以便在设备轮换时管理CALayer
/ CAGradientLayer
帧。
以下示例使用CAGradientLayer
但可以轻松映射到CALayer
或CAShapeLayer
案例。
#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