Color

Color 本身也是视图,它可以像形状和文本一样使用。


设置常规颜色

常规的设置颜色方法有以下几种:

设置语义颜色

还可以使用内置语义颜色:即不说是什么色调,而是描述其用途。(例如 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

基本设置方法

渐变 Gradients 是扩张型视图,其主要参数有:

其基本声明的初始化方法有以下几种:

// 颜色会被指定为一个数组,您可以拥有任意数量的颜色。默认情况下 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 线性渐变

线性渐变,梯度朝一个方向移动,因此我们为其提供如下起点和终点:

LinearGradient( colors: [.white, .black],  startPoint: .top,  endPoint: .bottom)

RadialGradient 径向渐变

径向渐变以圆形向外移动,因此我们指定了开始和结束半径,而不是指定方向 - 颜色应该从圆心开始和停止变化的距离。例如:

RadialGradient( colors: [.blue, .black],  center: .center,  startRadius: 20,  endRadius: 200)

AngularGradient 角渐变

它也被称为圆锥形或圆锥形渐变。这样可以使颜色围绕圆圈循环,而不是向外辐射,并且可以产生一些美丽的效果。

AngularGradient( colors: [.red, .yellow, .green, .blue, .purple, .red],  center: .center)

使用 stops 数组精确控制渐变

我们还可以使用渐变停止点(既可以指定颜色,也可以指定颜色应该沿渐变使用的距离)来实现精确控制渐变。可以把效果想象成在设计软件 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)

Mesh gradients 网格渐变

网格渐变是 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]
)

只需改变传入的值,网格渐变就可以制作精美的动画。例如我们使用 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
		    ])

}