【问题标题】:Using UIColor with CAShapeLayer将 UIColor 与 CAShapeLayer 一起使用
【发布时间】:2023-03-05 02:53:01
【问题描述】:

我将 RGB 颜色传递给 shapeLayer.fillColorshapeLayer.strokeColor,我的代码崩溃了。这是我尝试过的:

let shapeLayer = CAShapeLayer()
shapeLayer.fillColor = (UIColor(red: 57, green: 65, blue: 101, alpha: 1) as! CGColor)
shapeLayer.strokeColor = (UIColor(red: 57, green: 65, blue: 101, alpha: 1) as! CGColor)

如果我将我的 RGB 颜色写为:

UIColor(red: 57, green: 65, blue: 101, alpha: 1)

Xcode 提示我将其更改为:

(UIColor(red: 57, green: 65, blue: 101, alpha: 1) as! CGColor)

当我运行 Xcode 建议的修复程序时,我的应用程序崩溃了。为什么?

【问题讨论】:

  • 第一个问题:57/255.0 它应该介于 0 和 1 之间,而不是 0 和 255。第二个问题我不确定您是否可以像这样将 UIColor 转换为 CGColor。相反:shapeLayer.fillColor = UIColor(red: 57/255.0, green: 65/255., blue: 101/255., alpha: 1).cgColor 见:stackoverflow.com/questions/27821785/…

标签: ios swift uicolor rgba cgcolor


【解决方案1】:

首先参数red,green,bluealpha必须在0.0到1.0的范围内

其次,您必须将cgColor 传递给CGLayer,例如

let color = UIColor(red: 57.0/255.0, green: 65.0/255.0, blue: 101.0/255.0, alpha: 1)
shapeLayer.fillColor = color.cgColor
shapeLayer.strokeColor = color.cgColor

【讨论】:

    【解决方案2】:

    您将UIColor 类型转换为CGColor,这是错误的。并且 RGB 值必须在 0.0 到 1.0 的范围内,检查下面的代码。

    let circlePath = UIBezierPath(arcCenter: CGPoint(x: bounds.origin.x+60,y: bounds.origin.y+107), radius: CGFloat(6), startAngle: CGFloat(0), endAngle:CGFloat(7), clockwise: true)
    
    let shapeLayer = CAShapeLayer()
    shapeLayer.path = circlePath.cgPath
    circlePath.lineCapStyle = .round
    
    let color = UIColor(red: 57.0/255.0, green: 65.0/255.0, blue: 101.0/255.0, alpha: 1).cgColor
    
    shapeLayer.fillColor = color
    shapeLayer.strokeColor = color
    shapeLayer.lineWidth = 3.0
    self.layer.addSublayer(shapeLayer)
    

    【讨论】:

      【解决方案3】:

      修复代码

      你想要这样的东西:

      let shapeLayer = CAShapeLayer()
      shapeLayer.fillColor = UIColor(red: 57, green: 65, blue: 101, alpha: 1).cgColor
      shapeLayer.strokeColor = UIColor(red: 57, green: 65, blue: 101, alpha: 1).cgColor
      

      工作原理

      关于继承的警告

      Xcode 警告您关于该分配的 something 是正确的,因为您将 UIColor 分配给 CGColor 属性,但“修复我”的建议是错误的。 (Xcode 可能会这样做,因为它发现类名相似,但不完全相同。可能值得提交雷达。)

      您会经常看到这种情况的一个地方是将自定义 UITableViewCell 子类类型转换为基本单元类,但这在这里不起作用。 CGColor 不继承自 UIColorUIColor 也不继承自 CGColor。 CGColor 是一个CFTypeRef,UIColor 继承自`NSObject。

      其中一个与另一个不同

      现在,为什么这些颜色不同?

      CG 代表“Core Graphics”,它的级别低于定义 UIColor 类的 UIKit。一种颜色对象是 UIKit 和 Core Graphics 的一部分。

      文档说UIColor 是:

      一个存储颜色数据和不透明度(alpha 值)的对象。”

      再往下一点,概述说 UIColor 在内部将自己表示为预定颜色空间内的CGColor

      另一方面,CGColor 是:

      一组定义颜色的组件,颜色空间指定如何解释它们。"

      从概念上讲,非常相似,但并不完全相同。 UIColor 在 sRGBA 空间 (as noted here) 中定义,但 CGColor 将包含有关其所在颜色空间的信息。

      现在,您使用的动画层是 Core Animation 的一部分,它是另一个 Apple 框架。 Core Animation 不是 UIKit 的一部分,也不在 UIKit 之上,所以它的类不使用UIColor。 Core Animation 使用CGColor 来表示颜色。

      UIColor 很容易实例化,而且我们大部分时间都在 UIKit 领域。在我们的UIViews 和UIViewControllers 工作时,我们如何自定义CALayer 和朋友?幸运的是,UIColor 公开了自己的 CGColor 版本,带有 .cgColor 属性。

      关于色彩空间的说明

      其他一些答案指出,您需要传递 0.0 到 1.0 之间的值。确实如此,但需要注意的是,从 iOS 10 开始,Apple 为 iOS 添加了一些更宽颜色的功能。

      这意味着实际上可以传入小于 0.0 和大于 1.0 的值。来自UIColor documentation

      在扩展颜色空间中工作时,颜色值不会被限制在色域内,这意味着组件值可能小于 0.0 或大于 1.0。在 sRGB 显示器上显示时,此类颜色超出色域,无法准确渲染。

      您现在可能不需要担心色彩空间,但如果您想要在屏幕上显示颜色之外的其他事情,了解基本知识很重要。 (生成反色或补色就是一些例子。)

      Session 712 from WWDC 2016 (link) 深入介绍了这个新 API,我建议您在对基础知识更加熟悉后再看一看。

      最后,有一个Apple Tech Note (TN2313) 比我想象的更深入地讨论了这个问题。如果您想详细了解 iOS macOS 上的颜色和色彩空间,请阅读题为“OS X 和 iOS 中颜色管理的最佳实践”的技术说明。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多