iOS 渐变:如何在 Swift 中使用 CAGradientLayer

原文:iOS Gradients: How to Use to CAGradientLayer in Swift @App Code Labs

本教程将教你如何在 Swift 中使用 CAGradientLayer 创建 iOS 渐变。

在开始之前,你应该了解到还有另外三种创建渐变的方法。每种方法都有它们各自的优缺点,我们将简单讨论。

第一种,也是最基本的方法是:简单地使用 Photoshop 等设计工具生成的图片。这很简单,但不灵活:你必须确保图片设置了正确的分辨率,以适配你需要支持的屏幕尺寸。而且渐变是固定的,根本无法执行动画。在现代 iOS 编程中,我们一般尽可能避免使用图片。

第二种,使用 Core Graphics 框架 ,比 CAGradientLayer 更复杂,因为你需要在视图的渲染阶段操作图形上下文,但如果你的渐变需要高度动态,或者你的应用程序已经在执行 Core Graphics 渲染,那么它就会很有用。

第三种方法,直接使用 OpenGL,很容易就能达到最复杂的效果。只有在你已经使用 OpenGL 的情况下,例如在游戏中,它才有意义。如果你需要使用 OpenGL,那么你可能已经知道了!

何时使用 CAGradientLayer

CAGradientLayer 是易用性和功能性之间的最佳结合点。它很容易制作动画。它只有几个参数。而且它的速度很快。

无论你的应用是否需要为自定义 UI 组件提供静态渐变,还是为流行的控件提供动画渐变,你都应该考虑在做更复杂的事情之前使用 CAGradientLayer

基础知识

CAGradientLayer 是 iOS/macOS Core Animation 框架的一部分。它是 CALayer 的子类。它的速度很快,效率很高,因为和一般的 Core Graphics 框架一样,它是建立在 OpenGL 之上的。其实它也是相当简单的,但文档有些简略,所以本教程在这里对它进行更深入的解释。

CAGradientLayer,最简单的是定义了两个点之间的渐变,每个点有不同的颜色。如下图所示。

swift 复制代码
let gradient = CAGradientLayer()
gradient.frame = self.view.bounds
gradient.colors = [UIColor.red.cgColor, UIColor.blue.cgColor]
self.view.layer.addSublayer(gradient)

将渐变添加到视图上

以上代码显示了如何将渐变添加到视图中。让我们来简单释义。

实例化渐变:

swift 复制代码
let gradient = CAGradientLayer()

这样就创建了一个渐变图层。接下来,我们设置渐变图层的大小与视图大小相同:

swift 复制代码
gradient.frame = self.view.bounds

最后我们在视图中添加渐变图层:

swift 复制代码
self.view.layer.addSublayer(gradient)

需要记住的是,CAGradientLayerCALayer 的子类,因此它不能直接添加到 UIView 上,而是必须作为 sublayer 添加到视图的 layer 属性上

如果日后需要删除渐变图层,我们可以这样做:

swift 复制代码
gradient.removeFromSuperlayer()

如果图层层次结构过于复杂,图层的管理就会变得很困难。为了防止这种情况的发生,同时也是本着单一功能原则,一般来说,明智的做法是每个 UIView 只设置一个渐变

控制参数

到目前为止还不错,但我们能控制什么呢?有三件事我们可以改变:

  • 渐变的起点和终点;
  • 渐变的颜色顺序;
  • 渐变上颜色的位置;

改变起点和终点

起点和终点是在图层的单位坐标空间 中定义的,简单来说就是无论 CAGradientLayer 的尺寸是多少,为了在渐变中插值,我们认为左上角位置的坐标是 (0, 0),右下角位置的坐标是 (1, 1)

这也符合 Core Animation 坐标系,与 UIKit 系统相同,左上角为原点,如上图所示。(有些时候这会让人感到惊讶,尤其是当你习惯了 Core Graphics 框架,或者 macOS 系统的时候,这两个系统都使用左下角作为原点坐标系)。

默认的起点和终点,在上面的例子中被隐含使用,是 (0.5, 0.0)(0.5, 1.0),这相当于一个垂直向下的矢量。

在阅读 苹果官方文档 时,他们似乎认为你会使用 CATransform3D 来将渐变转换为你想要的方向,但这显然是很难做到的:即使在最好的情况下,这样的转换也可能令人费解。

幸运的是有一个更简单的方法,我们可以使用以下属性来设置渐变向量:

swift 复制代码
var startPoint: CGFloat
var endPoint: CGFloat

所以如果要定义一个从左往右,水平方向上变换的渐变 时,只要设置起点和终点分别是 (0.0, 0.5)(1.0, 0.5) 即可,如下图所示:

swift 复制代码
gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
gradient.endPoint = CGPoint(x: 1.0, y: 0.5)

从左上角到右下角的对角线渐变,则定义起点为 (0.0, 0.0),终点为 (1.0, 1.0),再次说明:

swift 复制代码
gradient.startPoint = CGPoint(x: 0.0, y: 0.0)
gradient.endPoint = CGPoint(x: 1.0, y: 1.0)

改变颜色顺序

颜色序列被指定为一个 CGColorRef 的数组:

swift 复制代码
var colors: [Any]?

在这个数组中设置任意数量的颜色,将创建一个在数组中所有颜色中进行插值的渐变。默认情况下,它将在渐变的几何体上均匀地插值 ,从 startPointendPoint。例如,下面的代码片段将产生彩虹效果:

swift 复制代码
let gradient = CAGradientLayer()
gradient.frame = CGRect(x: 0, y: 0, width: self.view.bounds.width, height: 100)
gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
gradient.colors = [UIColor.red.cgColor,
                   UIColor.orange.cgColor,
                   UIColor.yellow.cgColor,
                   UIColor.green.cgColor,
                   UIColor.blue.cgColor,
                   UIColor.purple.cgColor]
self.view.layer.addSublayer(gradient)

改变颜色的位置

如上所述,颜色是在渐变上均匀变化的。有时我们还需要控制颜色变化的位置。在 CAGradientLayer 的术语中,这些颜色被称为 colour stops,它们可以使用另一个数组来改变:

swift 复制代码
var locations: [NSNumber]?

这个数组中的值必须在 0 和 1 之间 ,并以小数的形式指定渐变几何上的颜色停止点。文档中指出,这个数组中的值必须是 "单向递增 " 的,这是数学术语,意思是说后一个值必须大于前一个值。仔细想想,这是有道理的--试图想象一个渐变会自己倒退是很奇怪的。

用图片来解释就容易多了。下面的代码片段与上面的彩虹代码相同,但颜色的终止点被压缩到了右侧。

swift 复制代码
let gradient = CAGradientLayer()
gradient.frame = CGRect(x: 0, y: 200, width: self.view.bounds.width, height: 100)
gradient.startPoint = CGPoint(x: 0.0, y: 0.5)
gradient.endPoint = CGPoint(x: 1.0, y: 0.5)
gradient.colors = [UIColor.red.cgColor,
                   UIColor.orange.cgColor,
                   UIColor.yellow.cgColor,
                   UIColor.green.cgColor,
                   UIColor.blue.cgColor,
                   UIColor.purple.cgColor]
gradient.locations = [0.0, 0.6, 0.7, 0.8, 0.9, 1.0]
self.view.layer.addSublayer(gradient)

结合其他属性,locations 属性让开发者可以完全控制渐变的插值。

关于 Locations 数组长度的说明

locations 数组的长度通常会与 colors 数组的长度一致。但是,如果它们不匹配,这并不是一个错误。这可能会造成意想不到的效果。也有可能有些开发者为了在渐变中得到 "平滑" 的颜色效果而故意这样做的,但他们的代码会更难理解,而且他们也不会达到任何通过使用设计中的数组所不能达到的效果。

总结

在这篇文章中,你学会了如何使用 CAGradientLayer 的所有属性。

首先,你学会了如何创建一个渐变并将其添加到视图中 。接下来你学会了如何设置渐变的起点和终点 ,如何指定颜色 ,以及最后如何使用 locations 数组控制渐变的停止点

希望这些信息已经足够让你真正开始工作,在你的应用程序中制作漂亮的渐变效果。

你在这里学到的所有属性都是可动画的。很快我将会写另一篇关于该主题的文章,所以一定要回来看看。

相关推荐
老白讲技术5 小时前
2026年国内APP开发与软件定制服务商能力观察:从AI应用到行业系统开发
大数据·人工智能·ai·app·软件需求·app开发
私人珍藏库7 小时前
[Android] 一木百宝箱-万能百宝箱+抖音去水印等几百种功能
android·人工智能·app·软件·多功能
_瑞1 天前
深入理解灵动岛
前端·ios·app
私人珍藏库2 天前
[Android] BBLL 开源第三方B哩电视TV端
android·app·生活·工具·多功能
私人珍藏库3 天前
[Android] zip解压缩管理-全格式压缩包一键解压+打包
android·app·生活·工具·多功能
Fansi6 天前
iOS 实时活动(Live Activity)开发指南
app
duanze7 天前
从零开始Android商业项目Vibe coding完全指南(八)
app·vibecoding
Bigger12 天前
Tauri (26)——托盘图标总对不上系统主题?一行 Template Image 搞定
前端·rust·app
duanze16 天前
从零开始Android商业项目Vibe coding完全指南(七)
app·vibecoding
方白羽22 天前
一份 AGENTS.md,让 Android AI 代码规范率飙升
android·app·客户端