Color
本身也是视图,它可以像形状和文本一样使用。
常规的设置颜色方法有以下几种:
使用系统内置颜色:例如 Color.blue
、 Color.green
、Color.indigo
使用自定义颜色:例如 Color(red: 1, green: 0.8, blue: 0)
<aside>
💡 提示:Color 也可以和 Text 一样使用 background 来设置颜色(如 .red 和 .green )。当使用 background()
修饰符时,SwiftUI 能够弄清楚 .red
实际上意味着 Color.red
。当使用颜色作为独立视图时,Swift 没有上下文来帮助它弄清楚 .red
的含义,因此需要具体说明我们的意思是 Color.red
。
</aside>
从资产目录加载自定义颜色,这也是同时支持浅色和深色模式的最简单方法
// 使用的是 Xcode 14 及更早版本
Color("YourColorName")
// 这是与 iOS 17 一起在 Xcode 15 中引入的
Color(.yourColorName)
还可以使用内置语义颜色:即不说是什么色调,而是描述其用途。(例如 Color.primary
)。设置语义颜色,可以根据用户的设备是在浅色模式还是深色模式下运行,自动适配使用黑色或是白色,节省了很多适配的工作。常见的语义有以下这些:
Color.primary // 用于主要要文本或元素
Color.secondary // 用于次要文本或元素,具有轻微的透明度
Color.tertiary // 用于第3层级文本或元素,具有轻微的透明度
Color.quaternary // 用于第4层级文本或元素,具有轻微的透明度
Color.accentColor // 用于强调元素的颜色,通常用于按钮或链接
Color.label // 主要文本标签的颜色
Color.secondaryLabel // 次要文本标签的颜色,通常比 label 更淡
Color.tertiaryLabel // 第三层级文本标签的颜色,通常比 secondaryLabel 更淡
Color.background // 用于视图的背景颜色
Color.secondarySystemBackground // 在系统背景中使用的次要颜色,适合用作内容区域的背景
Color.tertiarySystemBackground // 适用于更深层次的内容区域背景
background()
修改器除了设置颜色,还可以设置材质。它可以在下方的任何东西上应用磨砂玻璃效果,这能创建美丽的深度效果。
// 创建透明的毛玻璃效果
Color.clear.background(.regularMaterial)
// 从厚到薄,一共分5个等级
.background(.ultraThickMaterial)
.background(.thickMaterial)
.background(.regularMaterial)
.background(.thinMaterial)
.background(.ultraThinMaterial)
Color
是扩张型视图,会自动占用所有可用空间。虽然是扩张型地图,但也可以使用 frame()
修饰符来要求特定尺寸。
//例如,我们可以要求一个 200x200 的红色方块
Color.red.frame(width: 200, height: 200)
还可以指定最小和最大宽度和高度,具体取决于所需的布局。
例如,可以设置不超过 200 高的颜色,但其宽度必须至少为 200 ,但可以拉伸以填充其他东西未使用的所有可用宽度:
Color.red.frame(minWidth: 200, maxWidth: .infinity, maxHeight: 200)
//如果不希望内容也扩张到安全区域外,可以只给背景视图加忽略标记,而不要在ZStack里加
ZStack {
Color.gray
.edgesIgnoringSafeArea(.all)
...
}
渐变 Gradients 是扩张型视图,其主要参数有:
colors : [ ]
startPoint
、endPoint
其基本声明的初始化方法有以下几种:
// 颜色会被指定为一个数组,您可以拥有任意数量的颜色。默认情况下 SwiftUI 会将它们均匀地间隔开
LinearGradient(colors: [Color], startPoint: UnitPoint, endPoint: UnitPoint)
// 要制作水平渐变而不是垂直渐变,请使用 .leading 和 .trailing 作为起点和终点:
LinearGradient(gradient: Gradient(colors: [Color.red, Color.blue]), startPoint: .leading, endPoint: .trailing)
要制造其他的渐变样式,请用 RadialGradient 或 AngularGradient 代替 LinearGradient 即可(因类型不同,参数会略有不同):
线性渐变,梯度朝一个方向移动,因此我们为其提供如下起点和终点:
LinearGradient( colors: [.white, .black], startPoint: .top, endPoint: .bottom)
径向渐变以圆形向外移动,因此我们指定了开始和结束半径,而不是指定方向 - 颜色应该从圆心开始和停止变化的距离。例如:
RadialGradient( colors: [.blue, .black], center: .center, startRadius: 20, endRadius: 200)
它也被称为圆锥形或圆锥形渐变。这样可以使颜色围绕圆圈循环,而不是向外辐射,并且可以产生一些美丽的效果。
AngularGradient( colors: [.red, .yellow, .green, .blue, .purple, .red], center: .center)
我们还可以使用渐变停止点(既可以指定颜色,也可以指定颜色应该沿渐变使用的距离)来实现精确控制渐变。可以把效果想象成在设计软件 Figma 中画渐变的样子,就是定义渐变条上,具体哪个位置有哪个颜色即可:
stops
是一个数组,数组里的元素 Gradient.Stop
是一个包含颜色和位置的对象 (color: , location:)
<aside>
💡 所有的渐变类型,都可以提供 stops
停止点来取代简单的颜色。只需要将 colors
数组,替换为 stops
数组即可;
另外它们还可以在布局中用作独立视图,或者用作修改器的一部分。例如可以将它们用作文本视图的背景
</aside>
LinearGradient(
stops: [
Gradient.Stop(color: .orange, location: 0.45),
Gradient.Stop(color: .black, location: 0.55),
],
startPoint: .top,
endPoint: .bottom
)
// 简写:Swift 知道在这里创建了渐变 Stop ,所以作为快捷方式,可以直接编写 .init,而不需要写 Gradient.Stop
LinearGradient(
stops: [
.init(color: .white, location: 0.45),
.init(color: .black, location: 0.55),
],
startPoint: .top,
endPoint: .bottom
)
最简单的创建渐变的方式,只需在任何颜色后添加 .gradient
即可创建。SwiftUI 会自动将颜色转换为非常柔和的线性渐变。但它只适用于目标系统是 iOS 16 或更高版本。并且您无法控制它,并且您只能将它们用作背景和前景样式,而不是单个视图。
Text("Your content")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.foregroundStyle(.white)
.background(.red.gradient)
网格渐变是 SwiftUI 中最复杂的渐变类型,它只在 iOS 18 上可用。
创建网格渐变可以通过多种方式完成,但最简单的方法是指定渐变的宽度和高度、每种颜色的位置,然后指定要显示的颜色。出于性能原因,使用 SIMD2<Float>
指定位置,但您可以将它们创建为 X/Y 单位位置数组。
MeshGradient(
width: 2,
height: 2,
points: [
[0, 0], [1, 0], [0, 1], [1, 1]
],
colors: [.red, .green, .blue, .yellow]
)
points
数组就是 SIMD2<Float>
出现的地方:[0, 0]
是左上角, [1, 0]
是右上角。数组语法是创建这些 SIMD2<Float>
对象的最简单方法,但您可以将它们显式创建为 SIMD2(0.0, 0.0)
和类似的。只需改变传入的值,网格渐变就可以制作精美的动画。例如我们使用 TimelineView
定期重绘渐变,则可以使用 sin()
函数和一个小函数一些数学来获取 0 到 1 范围内的值,并在更大的网格中使用它:
TimelineView(.animation) { timeline in
let x = (sin(timeline.date.timeIntervalSince1970) + 1) / 2
// 它使用 3x3 网格,其中除中心元素之外的所有元素都是固定的
MeshGradient(
width: 3,
height: 3,
points: [
[0, 0], [0.5, 0], [1, 0],
[0, 0.5], [Float(x), 0.5], [1, 0.5],
[0, 1], [0.5, 1], [1, 1]
],
colors: [
.red, .red, .red,
.red, .orange, .red,
.red, .red, .red
])
}