75142913在线留言
SwiftUI 中的各种颜色详解Color、UIColor渐变颜色等_IOS开发_网络人

SwiftUI 中的各种颜色详解Color、UIColor渐变颜色等

Kwok 发表于:2021-10-11 10:11:13 点击:142 评论: 0

在UI开发中,颜色是一个非常重要的功能,SwiftUI中内置了强大的颜色处理解决方案。我们会在项目里使用Color,UIColor,CGColor这些颜色的类型,还有AngularGradient、LinearGradient、RadialGradient等渐变颜色视图。

一、Color 颜色

Color是SwiftUI内置了一个定义上下文颜色的数据类型。其内置了我们常用的标准颜色,black黑色、blue蓝色、brown棕色、cyan青色、gray灰色、green绿色、indigo 靛蓝色、mint 薄荷色、orange橙色、pink粉色、purple紫色、red红色、teal青色、white白色、yellow黄色等颜色和 clear清除颜色(透明)。

1、Color视图

Color符合View协议,所以我们可以将Color直接做为视图使用,以定义的颜色显示为矩形视图并布满可用的区域。

Color("background")//使用Assets.xcassets里定义的颜色
Color.green //内置颜色:绿色视图
Color(hue: 0.3, saturation: 0.4, brightness: 0.5, opacity: 0.6) //根据色调、饱和度和亮度值创建恒定颜色。
Color(hue: 0.3, saturation: 0.4, brightness: 0.5)//同上,但不使用透明度
Color(.sRGB, white: 0.9, opacity: 0.8)//恒定的灰度颜色。
Color(red: 0.1, green: 0.2, blue: 0.3)//通过reb值创建颜色
//通过RGB值创建颜色
Color(red: 1, green: 0, blue: 0.2)//通过reb值创建红色
Color(red: 255/255.0, green: 0/255.0, blue: 51/255.0,opacity: 1)//颜色与上相同,255/255.0 前面的255参数取值于photoshop

2、扩展Color让其可调用hex颜色值

如果上面这么多颜色API都不能满足的情况下,我们也可以直接使用hex颜色值来处理。扩展Color将16进制转换为RGB值并支持alpha通道。 

extension Color {
    init(hex: UInt, alpha: Double = 1) {
        self.init(
            .sRGB,
            red: Double((hex >> 16) & 0xff) / 255,
            green: Double((hex >> 08) & 0xff) / 255,
            blue: Double((hex >> 00) & 0xff) / 255,
            opacity: alpha
        )
    }
}

使用hex值设置颜色: 

Color(hex: 0x000000)//黑色
Color(hex: 0x000000, alpha: 0.2)//淡灰色

需要将网页里的#000000前面的#修改为0x即可。当然可以对扩展写更多的代码以达到支持以#开始的hex值。

3、从 UIColor或NSColor 颜色创建颜色。

基本上内置的颜色初始化就能满足我们开发中的需要,但有时候我们从UIKit转swiftUI的时候需要对原来的uiColor直接使用: 

#if os(iOS)
Color(uiColor: .link)//iOS 15+ 可用
#elseif os(macOS)
Color(nsColor: .linkColor)//macOS 12.0+可用
#endif

4、从cgColor创建颜色

Color(cgColor: .init(red: 0, green: 0, blue: 0, alpha: 0.1))//黑色的0.1透明:谈灰

5、颜色判断

因为颜色是符合Equatable协议的,所以我们可以使用==判断颜色: 

if(Color.black == Color(red: 0, green: 0, blue: 0)) {
    print("颜色一样")
}

6、应用颜色

可以通过 .foregroundColor、.fill、.background、.overlay等修改器应用颜色。 

Text("网络人 55mx.com")
    .padding()
    .foregroundColor(.red.opacity(0.8))
    .background(Capsule().fill(.yellow))
    .overlay(.clear)

二、UIColor 

UIColor是UIKit框架里的颜色,在SwiftUI里我们需要使用Color(uiColor: )的方式去转换为swiftUI可用的颜色,和Color不同的是UIColor有更多操作的API,可以知道 颜色值、色调、饱和度、亮度值等信息。

在SwiftUI中Color是View视图,而UIColor是UIKit中存储颜色信息的一个重要的类,一个UIColor对象包含了颜色和透明度的值,它的颜色空间已经针对IOS进行了 优化。UIColor包含了一些类方法用于创建一些最常见的颜色,如白色,黑色,红色,透明色等,这些颜色的色彩空间也不尽相同(白色和黑色是 kCGColorSpaceDeviceGray,红色的色彩空间是kCGColorSpaceDeviceRGB)。 

init(white: CGFloat, alpha: CGFloat)//创建灰度值。白度为 0% (0.0) 时为黑色,白度为 100% (1.0) 时为纯白色
init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat)//基于RGB的另一种表示方式
init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)//RGB+通道
init(displayP3Red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)//RGB的另一种用法
init(cgColor: CGColor)//使用CGColor 核心图形颜色
init(patternImage image: UIImage)//使用来源于UIImage的图片颜色
init(ciColor: CIColor)//使用ciColor颜色
init(dynamicProvider: @escaping (UITraitCollection) -> UIColor)//使用一个闭包返回的颜色

每个使用CGFloat的值都应该在0.0到1.0之间,分别指该颜色组件的完全缺失或最大数量。因此,这意味着即使您有十进制或十六进制格式的纯RGB值,也必须将它们除以小数255才能看到真实的RGB值(上面Color里有演示)。

.overlay(Color(uiColor: UIColor.darkText.withAlphaComponent(0.3)))//uiColor参数需要iOS15+

UIColor里也有很多系统内置的颜色:

/******** 固定颜色 ************/
UIColor.black//黑色
UIColor.darkGray //深灰
UIColor.lightGray //浅灰
UIColor.white //白色
UIColor.gray //灰色
UIColor.red //红色
UIColor.green //绿色
UIColor.blue //蓝色
UIColor.cyan //蓝绿色
UIColor.yellow //黄色
UIColor.magenta //紫红色
UIColor.orange //橘黄色
UIColor.purple //紫色
UIColor.brown //褐色
UIColor.clear //透明色

/******** 自适应颜色 ************/
UIColor.systemBlue //系统蓝色
UIColor.systemBrown //系统棕色
UIColor.systemGreen //系统绿色
UIColor.systemIndigo //系统靛蓝色
UIColor.systemOrange //系统橙色
UIColor.systemPink //系统粉红色
UIColor.systemPurple //系统紫色
UIColor.systemRed //系统红色
UIColor.systemTeal //系统青色
UIColor.systemYellow //系统黄色

/******** 适应性强的灰色 ************/
UIColor.systemGray //标准基灰色
UIColor.systemGray2 //二级灰色阴影
UIColor.systemGray3 //三级灰色阴影
UIColor.systemGray4 //四级灰色阴影
UIColor.systemGray5 //五级灰色阴影
UIColor.systemGray6 //六级灰色阴影

/******** 标签颜色 ************/
UIColor.label //文本标签的颜色。
UIColor.secondaryLabel //次要内容的文本标签的颜色。
UIColor.tertiaryLabel //三级内容的文本标签的颜色。
UIColor.quaternaryLabel //四元内容的文本标签的颜色。

/******** 填充颜​​色 ************/
UIColor.systemFill //薄和小形状的覆盖填充颜色。
UIColor.secondarySystemFill //中等大小形状的叠加填充颜色。
UIColor.tertiarySystemFill //大型形状的叠加填充颜色。
UIColor.quaternarySystemFill //包含复杂内容的大区域的叠加填充颜色。

/******** 背景颜色 ************/
UIColor.systemBackground //界面主背景的颜色。
UIColor.secondarySystemBackground //分层在主背景之上的内容颜色。
UIColor.tertiarySystemBackground //分层在次要背景之上的内容的颜色。
UIColor.systemGroupedBackground //分组界面的主背景颜色。
UIColor.secondarySystemGroupedBackground //分层在分组界面主背景之上的内容颜色。
UIColor.tertiarySystemGroupedBackground //次要背景之上的内容颜色。

/******** 其它颜​​色 ************/
UIColor.separator //细边框或分隔线的颜色。
UIColor.opaqueSeparator //边框或分隔线的颜色。
UIColor.link //链接的指定颜色。
UIColor.darkText //浅色背景上文本的不可适应的系统颜色。
UIColor.lightText //深色背景上文本的不可适应的系统颜色。
UIColor.placeholderText //占位符文本的颜色。

三、CGColor

以CG开头都是系统核心图形参数(Core Graphic), CGColor是系统中的基本颜色表示。就像CGPoint、CGFloat、CGSize一样。其API不多,我们主要使用color.cgColor的Color变量从Color转为CGColor。而且这是一个可选类型(optional),不能保存100%成功。

CGColor可以转为UIColor然后又可以转回Color。所以它们几个都可以通过直接或者间接的方法转换的。

四、渐变颜色

SwiftUI 有一种内置的方法可以将渐变颜色应用于其视图。有三种类型的渐变:

SwiftUI中的各种颜色详解ColorUIColor渐变颜色等

在我们访问每个渐变之前,让我们从它们的共同组件Gradient 开始。

Gradient是一个结构体,它包含用于渲染所有类型的渐变的信息,该渐变表示为一个色标数组。Gradient.Stop是一个结构体,表示渐变中的每种颜色和位置(范围为 0 到 1)。

你可以像这样用Gradient.Stop初始化它: 

Gradient(stops: [.init(color: .black, location: 0),
                 .init(color: .pink, location: 0.5)

如果您希望所有 **Gradient.Stop ** 的位置均等分布,也可以使用Color对其进行初始化。 

Gradient(colors: [.black, .pink])
// 上下结果相同
Gradient(stops: [.init(color: .black, location: 0),
                 .init(color: .pink, location: 1)

它可以包含两个以上的停靠点。

Gradient(colors: [.black, .pink, .black])

以下是初始化Gradient的不同方法的示例。

let gradient = Gradient(colors: [.black, .pink])
let gradient2 = Gradient(colors: [.black, .pink, .black])
let gradient3 = Gradient(stops: [.init(color: .black, location: 0),
                                  .init(color: .pink, location: 0.5)
])

 SwiftUI中的各种颜色详解ColorUIColor渐变颜色等

(上)两种颜色的渐变均匀分布,(中)三种颜色的渐变均匀分布,(下)两种颜色的渐变不均匀分布 

1、AngularGradient 角梯度渐变

角度梯度也称为“圆锥”梯度。当角度相对于中心点和定义的开始和结束角度发生变化时,此渐变应用颜色函数。如果 endAngle - startAngle > 2π,则渐变仅绘制最后一个完整的转弯。如果 endAngle - startAngle < 2π,渐变会用渐变位置 1 和 0 定义的颜色填充缺失区域,在缺失区域的中间过渡到两者之间。渐变将单位空间中心点映射到每个填充渐变的形状的边界矩形中。

AngularGradient 随着角度的变化应用颜色;您定义将应用渐变的开始和结束角度。有几个变量可以初始化 AngularGradient。

以下是最简单的形式。您定义圆的中心,渐变将从 0 度(最右侧)开始,其余颜色将顺时针绘制,直到完成圆。

AngularGradient(gradient: gradient, center: .center)

如果您不想从 0 度开始,则可以使用第二种形式,您可以在其中指定angle(起始角度)。

AngularGradient(gradient: gradient, center: .center, angle: .degrees(90))

如果要指定终止角,则必须使用定义startAngle和的最后一种形式endAngle。

AngularGradient(gradient: gradient, center: .center, startAngle: .degrees(90), endAngle: .degrees(180))

通过一个视图详解:

struct AngularSample: View {
    let gradient = Gradient(colors: [.red, .orange, .yellow, .green, .blue, .purple])    
    var body: some View {
        HStack {
            VStack {
                Rectangle()
                    .fill(
                        AngularGradient(gradient: gradient, center: .center)
                    )
                    .frame(width: 200, height: 200)
            }
            VStack {
                Rectangle()
                    .fill(
                        AngularGradient(gradient: gradient, center: .center, angle: .degrees(90))
                    )
                    .frame(width: 200, height: 200)
            }
            VStack {
                Rectangle()
                    .fill(
                        AngularGradient(gradient: gradient, center: .center, startAngle: .degrees(90), endAngle: .degrees(180))
                    )
                    .frame(width: 200, height: 200)
            }
        }
    }
}

SwiftUI中的各种颜色详解ColorUIColor渐变颜色等

a.终止角 - 起始角 = 2π

这是起始角和终止角形成一个完整圆的正常情况。每种颜色都会均匀分布。

 

AngularGradient(gradient: gradient, center: .center)
AngularGradient(gradient: gradient, center: .center, angle: .degrees(0))
AngularGradient(gradient: gradient, center: .center, startAngle: .degrees(0), endAngle: .degrees(360))

b.终止角 - 起始角 > 2π

这是总角度大于圆的情况。额外的角度会吃掉第一个圆圈部分。以下是角度梯度的示例。

AngularGradient(gradient: gradient, center: .center, startAngle: .degrees(0), endAngle: .degrees(360))
AngularGradient(gradient: gradient, center: .center, startAngle: .degrees(0), endAngle: .degrees(360 + 45))
AngularGradient(gradient: gradient, center: .center, startAngle: .degrees(0), endAngle: .degrees(360 + 360))

SwiftUI中的各种颜色详解ColorUIColor渐变颜色等

 (左)一个完整的圆,(中)一个圆和45度角,(右)一个两个圆

我希望你关注最后一个例子,其中结束角是 360 + 360 度,这是两个圆。在这种情况下,您只会看到三种颜色(绿色、蓝色、紫色),因为六种颜色渐变是在 2 个圆圈的总角度中呈现的,因此前三种颜色(红色、橙色、黄色)将绘制在第一个圆圈上将被第二个圆圈覆盖。这就是为什么在开始时您只能看到三种最终颜色(绿色、蓝色、紫色)和一点黄色(第一个圆圈的最后一种颜色)。

c.终止角 - 起始角 < 2π

最后一种情况是起点和终点角度没有形成一个完整的圆。缺失的区域(开始和结束之间)将均匀地涂上渐变的第一种颜色和最后一种颜色。

//请注意,角度可以是负值,它将逆时针旋转。
AngularGradient(gradient: gradient, center: .center, startAngle: .degrees(-90), endAngle: .degrees(180))
AngularGradient(gradient: gradient, center: .center, startAngle: .degrees(0), endAngle: .degrees(90))
AngularGradient(gradient: gradient, center: .center, startAngle: .degrees(90), endAngle: .degrees(270))

 SwiftUI中的各种颜色详解ColorUIColor渐变颜色等

 所有这些梯度都是ShapeStyle和View协议,所以你可以在任何需要这两个协议的地方使用它们。我现在能想到的常见地方是一个独立的View、.background.fill和.strokea Shape。

2、LinearGradient线性梯度

这是最常见的渐变类型。这是我用来渲染上面初始化Gradient例子的那个。渐变沿轴应用颜色函数,由其起点和终点定义。渐变将单位空间点映射到每个填充渐变的形状的边界矩形中。

简而言之,您使用UnitPoint指定渐变的起点和终点,一个表示 x、y 坐标空间(范围从 0 到 1)的结构体,并且渐变停止将根据每个停止的位置沿该路径呈现。

SwiftUI已预定义UnitPoint,.zero,.center,leading,trailing,top,bottom,topLeading,topTrailing,bottomLeading,和bottomTrailing。如果您有特殊需要,您可以像普通结构一样创建自己的UnitPoint。

UnitPoint(x: 1, y: 0) // .topTrailing

以下是LinearGradient不同设置的示例:

let gradient = Gradient(colors: [.black, .pink])
LinearGradient(gradient: gradient, startPoint: .leading, endPoint: .topTrailing)
LinearGradient(gradient: gradient, startPoint: .top, endPoint: .bottom)
LinearGradient(gradient: gradient, startPoint: .bottomTrailing, endPoint: .topLeading)

SwiftUI中的各种颜色详解ColorUIColor渐变颜色等

3、RadialGradient 径向梯度

渐变应用颜色函数作为距中心点的距离,缩放以适合定义的开始和结束半径。渐变将单位空间中心点映射到每个填充渐变的形状的边界矩形中。

RadialGradient 可能看起来与 LinearGradient 不同,但概念是完全相同的。唯一的区别是不是定义起点和终点,而是定义起点半径、终点半径和渐变的中心。渐变将绘制为围绕中心的圆形并向外移动到末端半径。

RadialGradient(gradient: gradient, center: .center, startRadius: 1, endRadius: 100)

center是UnitPoint就像我们在LinearGradient 中讨论的那样。startRadius和endRadiusareCGFloat表示以点为单位的半径。

以下是RadialGradient不同设置的示例:

struct RadialSample: View {
    let gradient = Gradient(colors: [.black, .pink])
    
    var body: some View {
        HStack {            
            VStack {
                Rectangle()
                    .fill(
                        RadialGradient(gradient: gradient, center: .center, startRadius: 1, endRadius: 100)
                )
                    .frame(width: 200, height: 200)
                Text("radius 1 to 100")
                    .fontWeight(.semibold)
                    .foregroundColor(.white)
            }
            VStack {
                Rectangle()
                    .fill(
                        RadialGradient(gradient: gradient, center: .center, startRadius: 1, endRadius: 100)
                )
                    .frame(width: 200, height: 100)
                Text("radius 1 to 100")
                    .fontWeight(.semibold)
                    .foregroundColor(.white)
            }
            VStack {
                Rectangle()
                    .fill(
                        RadialGradient(gradient: gradient, center: .center, startRadius: 1, endRadius: 50)
                )
                    .frame(width: 200, height: 100)
                Text("radius 1 to 50")
                    .fontWeight(.semibold)
                    .foregroundColor(.white)
            }
        }
    }
}

SwiftUI中的各种颜色详解ColorUIColor渐变颜色等

五、Material背景材料

Material是应用于背景.background与覆盖 .overlay的一种材料(质)效果,是今年iOS 15新增的类型,虽然不属于颜色,但与颜色并无差别,材质不是视图,但添加材质就像在修改后的视图与其背景之间插入半透明层:

SwiftUI中的各种颜色详解ColorUIColor渐变颜色等

材质提供的模糊效果不是简单的不透明度。相反,它使用特定于平台的混合,产生类似于重度磨砂玻璃的效果。您可以使用复杂的背景更轻松地看到这一点,例如图像:

SwiftUI中的各种颜色详解ColorUIColor渐变颜色等

ZStack {
    Image("chili_peppers")
        .resizable()
        .aspectRatio(contentMode: .fit)
    Label("Flag", systemImage: "flag.fill")
        .padding()
        .background(.regularMaterial)
}

对于物理材料,背景颜色通过的程度取决于厚度。效果也随着外观的明暗而变化:

SwiftUI中的各种颜色详解ColorUIColor渐变颜色等

如果您需要材质具有特定形状,则可以使用修改器。例如,您可以创建带圆角的材质:background(_:in:fillStyle:)

ZStack {
    Color.teal
    Label("Flag", systemImage: "flag.fill")
        .padding()
        .background(.regularMaterial, in: RoundedRectangle(cornerRadius: 8))
}

SwiftUI中的各种颜色详解ColorUIColor渐变颜色等

材质会模糊应用中的背景,但不会模糊屏幕上应用背后的背景。例如,主屏幕上的内容不会影响小部件的外观。添加材质时,前景元素会呈现出活力,前景和背景颜色的上下文特定混合可提高对比度。但是,使用设置自定义前景样式(不包括分层样式,例如)会禁用活力。

static var ultraThinMaterial: Material 一种主要是半透明的材料。
static var thinMaterial: Material 一种比不透明更半透明的材料。
static var regularMaterial: Material 一种有点半透明的材料。
static var thickMaterial: Material 一种比半透明更不透明的材料。
static var ultraThickMaterial: Material 一种几乎不透明的材料。
除非注明,网络人的文章均为原创,转载请以链接形式标明本文地址:https://www.55mx.com/post/164
标签:颜色Kwok最后编辑于:2021-10-11 11:11:17
0
感谢打赏!

《SwiftUI 中的各种颜色详解Color、UIColor渐变颜色等》的网友评论(0)

本站推荐阅读

热门点击文章