[英]Autorotation of CALayer on iPhone rotation
I have a UIViewController where I am adding a CALayer subclass to the view's layer:我有一个 UIViewController,我在其中向视图层添加了 CALayer 子类:
[self.view.layer addSublayer:myObject.backgroundLayer];
When I rotate the device, the view rotates, but the CALayer doesn't.当我旋转设备时,视图会旋转,但 CALayer 不会。 It sort of gets shunted off to the left, still in portrait view.它有点被分流到左边,仍然是纵向视图。
Is there a way to make sublayers rotate automatically or do I need to apply a transform?有没有办法让子图层自动旋转,或者我需要应用变换吗?
With Swift 4 / iOS 11, according to your needs, you may choose one of the 6 following examples in order to manage your CALayer
/ CAGradientLayer
frame upon a device rotation.使用 Swift 4 / iOS 11,根据您的需要,您可以选择以下 6 个示例之一,以便在设备旋转时管理您的CALayer
/ CAGradientLayer
框架。
The examples below use CAGradientLayer
but can easily be mapped to CALayer
or CAShapeLayer
cases.下面的示例使用CAGradientLayer
但可以轻松映射到CALayer
或CAShapeLayer
案例。
UIViewController
viewDidLayoutSubviews()
覆盖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
}
}
UIViewController
loadView()
, subclassing UIView
and overriding UIView
layoutSubviews()
覆盖UIViewController
loadView()
, UIView
和覆盖UIView
layoutSubviews()
LayerView.swift图层视图.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 (alternative) 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视图控制器.swift
import UIKit
class ViewController: UIViewController {
let layerView = LayerView()
override func loadView() {
view = layerView
}
}
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
})
*/
}
}
UIViewController
loadView()
, subclassing UIView
and overriding UIView
layerClass
覆盖UIViewController
loadView()
, layerClass
UIView
和覆盖UIView
layerClass
LayerView.swift图层视图.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视图控制器.swift
import UIKit
class ViewController: UIViewController {
let layerView = LayerView()
override func loadView() {
view = layerView
}
}
UIViewController
loadView()
, subclassing UIView
and overriding CALayerDelegate
layoutSublayers(of:)
覆盖UIViewController
loadView()
, CALayerDelegate
UIView
和覆盖CALayerDelegate
layoutSublayers(of:)
LayerView.swift图层视图.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视图控制器.swift
import UIKit
class ViewController: UIViewController {
let layerView = LayerView()
override func loadView() {
view = layerView
}
}
UIViewController
loadView()
, subclassing UIView
, overriding UIView
layerClass
, subclassing CALayer
and overriding CALayer
layoutSublayers()
覆盖UIViewController
loadView()
,子类化UIView
,覆盖UIView
layerClass
,子类化CALayer
和覆盖CALayer
layoutSublayers()
Layer.swift层.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图层视图.swift
import UIKit
class LayerView: UIView {
override public class var layerClass: AnyClass {
return Layer.self
}
}
ViewController.swift视图控制器.swift
import UIKit
class ViewController: UIViewController {
let layerView = LayerView()
override func loadView() {
view = layerView
}
}
Sources:资料来源:
You need to manage the rotation of the CALayer yourself.您需要自己管理 CALayer 的旋转。 I believe that 0,0 stays at the same place and that the size is changed to match the new orientation, so if you wanted to do something yourself, you'd need to manage the addition of the rotation transformation yourself.我相信 0,0 保持在同一个位置,并且大小会改变以匹配新的方向,所以如果你想自己做一些事情,你需要自己管理旋转变换的添加。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.