iPhone 旋转时 CALayer 自动旋转

2024-05-25

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

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

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

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


使用 Swift 4 / iOS 11,根据您的需求,您可以选择其中之一6 下面的例子为了管理您的CALayer / CAGradientLayer设备旋转时的框架。

下面的例子使用CAGradientLayer但可以很容易地映射到CALayer or CAShapeLayer cases.


#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<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(), 子类化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
    }

}

Sources:

  • 媒体网站 https://medium.com/@marcosantadev/calayer-and-auto-layout-with-swift-21b2d2b8b9d1
  • github.com https://github.com/imanoupetit/RotateGradients
  • 开发者.apple.com https://developer.apple.com/documentation/quartzcore/calayerdelegate/2097257-layoutsublayers
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

iPhone 旋转时 CALayer 自动旋转 的相关文章

随机推荐

  • 为什么 np.linalg.norm(..., axis=1) 比写出向量范数公式慢?

    标准化矩阵的行X对于单位长度 我通常使用 X np linalg norm X axis 1 keepdims True 在尝试优化算法的此操作时 我非常惊讶地发现在我的机器上写出标准化的速度大约快了 40 X np sqrt X 0 2
  • SQL Server 中临时表的使用

    这是一个悬而未决的问题 但我真的很想听听人们的意见 我很少使用显式声明的临时表 表变量或常规 tmp 表 因为我相信不这样做会导致更简洁 可读和可调试的 T SQL 我还认为 在需要时 例如当您在查询中使用派生表时 SQL 可以比我更好地利
  • 关闭 bootstrap-select / select2 的自动对焦

    http www bootply com YAQrE52K6X http www bootply com YAQrE52K6X dataCombo selectpicker multiple true div class container
  • ZipResourceFile 无法解析为类型

    我正在尝试重写我的应用程序以使用 APK 扩展文件 我一直在关注这里的文档http developer android com google play expansion files html http developer android
  • Scala 函数定义参数列表中不同的括号样式

    Scala 中以下两个函数定义有什么区别 1 def sum f Int gt Int a Int b Int Int code 2 def sum f Int gt Int a Int b Int Int code SBT 的控制台 RE
  • UITableView 中具有多个部分的搜索控制器

    我有一个 UIViewController 其中有一个 UITableView 在该表视图内我有多个部分 其中有一些项目 我必须在该表视图内使用项目名称进行搜索 我已经在我的视图控制器中声明了这一点 let searchController
  • 使用 @Input() 时出现 TypeScript 错误

    我正在尝试使用 Angular 4 开发一个应用程序 但是我在使用时收到一条错误消息 Input inputProducts products Product 错误是 tslint 在 ProductListComponent 类中 指令输
  • 在未连接智能卡的情况下使用 winscard.dll (PC/SC) 发送 APDU

    我正在尝试将 APDU 命令发送到读卡器本身而不是智能卡 我使用的测试命令打开和关闭射频场 如果我第一次连接到智能卡 则此命令通过 SCardTransmit 发送 但是 一旦 RF 场关闭 卡就会断开连接 我无法发送另一个 APDU 来打
  • MongoDB req.body 问题

    我有一个非常简单的 Mongo 设置 如下所示 这非常适合从输入字段获取数据并保存数据 一切都在工作 我的问题 我将如何循环遍历前端的 jobs 变量并设置数据 以便它适用于我的模型 不知何故 我需要将其输入到输入中 以便我可以 req b
  • 如何在 Django 管理中使用自定义表单字段作为模型字段?

    我想让 Django 管理员使用自定义表单字段来输入某些字段 到目前为止 我制作了一个自定义模型字段 该字段绑定了表单字段 效果很好 但它引入了一个不必要的模型字段 不会增加任何好处 我想可以使用自定义管理表单以某种方式完成 请参阅http
  • 将 css 类添加到 Ember.js 中的

    如何将CSS类添加到特定路线上的body标签 我尝试使用body在车把模板中添加标签但不起作用 Update 经过一番谷歌搜索后 我找到了这个解决方案 不确定这是最好的方法 但它确实有效 App SomeRoute Em Route ext
  • 我可以在 RestEasy 中指定用于方法结果转换的 jackson @JsonView 吗?

    我正在使用基于的序列化模型 JsonView 我通常配置杰克逊ContextResolver像这样 Override public ObjectMapper getContext Class
  • OCMockito everything() 用于原始类型

    对于方法签名 void insertValue NSUInteger value 我想看看是否有任何值的 insertValue 永远不会被调用 verifyCount test never insertValue 0 由于编译器抱怨 ev
  • Pandas cut 方法不包括下限

    我正在尝试对包含 0 到 100 范围内的年龄的数据帧列进行分箱 当我尝试使用垃圾箱来包含零年龄时 它不起作用 这是一个使用包含我的数据范围的列表的演示 pd cut pd Series range 101 0 24 49 74 100 范
  • Recycler查看可见项目的数量

    我正在我的应用程序中创建一个水平 RecyclerView 它必须一次在屏幕上显示 2 个图像 因此每个图像的宽度必须为屏幕的 50 目前它工作正常 但每个项目都会占用屏幕的所有宽度 这是我的代码 mRecyclerView Recycle
  • Unity3D如何连接NavMesh和NavMeshAgent

    我在编辑器中收到此错误 SetDestination can only be called on an active agent that has been placed on a NavMesh 这些是我在解决问题时尝试的步骤 将 Nav
  • 快速计算三角形与单位正方形的交面积

    在我当前的项目中 我需要计算无限网格中三角形和单位正方形的交集面积 对于每个三角形 由三对浮点数给出 我需要知道面积 在区间内 0 1 它与它相交的每个正方形都有共同点 现在我将两者 三角形和正方形 转换为多边形并使用Sutherland
  • 如何实现 Eclipse 清理和构建(又名重建)?

    我删除了我的 binEclipse Indigo 中的文件夹 与 Helios 非常相似 现在我想知道如何重建我的 Java 项目 我只是找不到像 Netbeans 中那样的按钮 对于 Eclipse 您可以在下面找到重建选项项目 gt 清
  • Visual Studio 2010 库链接错误

    当我尝试在项目中使用 DCMTK MT 库时 出现以下链接错误 我确信这些错误与VS2010的ws2 32 lib wsock32 lib netapi32 lib有关 但我已经将这三个库添加到项目属性中 您可以看到库已被搜索 如下所示 这
  • iPhone 旋转时 CALayer 自动旋转

    我有一个 UIViewController 其中我将 CALayer 子类添加到视图层 self view layer addSublayer myObject backgroundLayer 当我旋转设备时 视图会旋转 但 CALayer