ビューのレイヤーに CALayer サブクラスを追加する UIViewController があります。
[self.view.layer addSublayer:myObject.backgroundLayer];
デバイスを回転すると、ビューは回転しますが、CALayer は回転しません。縦向きのビューのままで、左側に分流されます。
サブレイヤーを自動的に回転させる方法はありますか、それとも変換を適用する必要がありますか?
ビューのレイヤーに CALayer サブクラスを追加する UIViewController があります。
[self.view.layer addSublayer:myObject.backgroundLayer];
デバイスを回転すると、ビューは回転しますが、CALayer は回転しません。縦向きのビューのままで、左側に分流されます。
サブレイヤーを自動的に回転させる方法はありますか、それとも変換を適用する必要がありますか?
Swift 4 / iOS 11 では、必要に応じて、デバイスの回転時に/フレームを管理するために、次の 6つの例のいずれかを選択できます。CALayer
CAGradientLayer
以下の例では使用していますが、またはケースCAGradientLayer
に簡単にマッピングできます。CALayer
CAShapeLayer
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()
、サブクラス化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
}
}
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()
、サブクラス化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
}
}
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
}
}
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
}
}
ソース:
CALayer の回転は自分で管理する必要があります。0,0 は同じ場所にとどまり、新しい向きに合わせてサイズが変更されると思います。そのため、自分で何かをしたい場合は、回転変換の追加を自分で管理する必要があります。