解锁构建UI的新姿势——SwiftUI
注:
- 文中代码、视频及图片素材均来源于官方文档
- 本期源码:官方下载地址
一、创建SwiftUI项目
- 使用SwiftUI,确保Mac上跑的是macOS 10.15 beta版,或以上版本。
- Xcode为11 beta版,或以上版本。
步骤1
打开Xcode,单击Create a new Xcode project
,或选择File > New > Project
。
步骤2
选择iOS菜单下的的Single View App
模板,然后单击Next
。
步骤3
输入"Landmarks"(做一个包含各种地标元素的地标集项目)作为项目名称,选中Use SwiftUI
复选框,Next
,选择在Mac上保存该项目的位置。
步骤4
在Xcode左手边的文件导航器中,单击选择ContentView.swift
。
默认情况下,SwiftUI会声明两个结构体,第一个结构体遵循
View
协议——用来描述视图的内容和布局;第二个结构体声明该视图的预览方式。
/// ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Hello World")
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
复制代码
预览: ⬇️
步骤5
在预览画布中,单击Resume
按钮以显示预览。
如果画布不可见,选择
Editor > Editor and Canvas
以显示它。
步骤6
在代码内body属性里,将"Hello World"更改为"Hello SwiftUI"。
更改body内视图的属性,预览也将实时更新。
/// ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
/// "这里更改为Hello SwiftUI!,即可在预览中实时显示。"
Text("Hello SwiftUI!")
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
复制代码
预览: ⬇️
二、自定义文本视图
更改UI的方式有两种:1.改代码;2.改属性检查器选项。
无论使用哪种方式,代码都会保持更新。
接下来,您将使用属性检查器自定义TextView。
步骤1
在预览画布中,按住Command
键的同时单击"Hello SwiftUI"文本,会弹出可选菜单,点击Inspect...
此选项即可打开文本视图的属性检查器。
注:不同的View,对应的不同的属性检查器内容。
步骤2
如图,将文本更改为"Turtle Rock"(地名:中文名叫昂装,位于中国香港),这是将在应用程序中显示的第一个地标。
步骤3
如图将字体改为"Title"
步骤4
为Text
添加代码.color(.green)
,将文本改为绿色。
SwiftUI中,
.color(.green)
类似的点方法也叫做modifier
(叫啥名不重要),调用后返回该视图本身,因此类似链式编程,可不停往后面追加所谓的modifier
。
/// ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Turtle Rock")
.font(.title)
/// "步骤4: 设置颜色为绿色"
.color(.green)
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
复制代码
预览: ⬇️
????代码即视图,视图即代码 ????。即使使用属性检查器更改或删除属性时,Xcode也会立即更新代码以匹配。看步骤5 ⬇️
步骤5
按住Command
键并单击"Turtle Rock"文本视图,点击Inspect...
进入其属性检查器,单击Color
右侧下拉菜单并选择"Inherited"(继承系统默认值的意思),效果就是把文本颜色再回原来的黑色。
步骤6
此时,Xcode会自动删除.color(.green)
这行代码以响应上面的更改。
/// ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
Text("Turtle Rock")
.font(.title)
/// "步骤6: Xcode自动删除原来设置颜色的代码,以响应属性检查器的更改"
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
复制代码
预览: ⬇️
三、使用Stacks布局View
在上一节中,创建了地标名字的文本视图,接着我们继续添加包含该地标详细信息(如该地点著名的公园名称和所在州)的文本视图。
创建SwiftUI的视图时,我们可以在视图的body属性中描述其内容、布局和行为,但是body内只返回单个视图。我们可以将多个视图组合放到Stack
中。
Stack
:可以理解为存放View的容器,扔进去的View们由Stack
摆布,摆布的方式有View们横着排、竖着排和从后往前排等
HStack:全称Horizontal Stack,水平排列,也就是横着排
VStack:全称Vertical Stack,垂直排列,也就是竖着排
本节用Stack
干两个事儿:
1.公园名称和所在州名称对应的俩文本视图横着排
2.地标名字的文本视图搁1上面,如图
属性检查器除了可以在预览画布里展开,代码中同样奏效:
步骤1
按住Commond
键并单击Text("Turtle Rock")
代码行,选择Embed in VStack
。
接下来,拖一个文本视图添加到这个VStack
中。
步骤2
单击Xcode右上角的+
按钮,然后将Text
视图拖动到代码中Turtle Rock
整个文本视图后面的位置。
步骤3
将拖进来的文本视图的文本替换为"Joshua Tree National Park"。
/// ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Text("Turtle Rock")
.font(.title)
/// "步骤3: 拖进来,换个文本"
Text("Joshua Tree National Park")
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
复制代码
预览: ⬇️
自定义位置以匹配所需布局。
步骤4
字体设置为".subheadline"。
/// ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
VStack {
Text("Turtle Rock")
.font(.title)
Text("Joshua Tree National Park")
/// "步骤4: 设置字体为 subheadline"
.font(.subheadline)
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
复制代码
预览: ⬇️
步骤5
设置VStack
对齐方式为左对齐。
默认情况下,
VStack
沿视图的中轴线对齐。
/// ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) { // "步骤5: 设置对齐方式为左对齐"
Text("Turtle Rock")
.font(.title)
Text("Joshua Tree National Park")
.font(.subheadline)
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
复制代码
预览: ⬇️
接下来,在"Joshua Tree National Park"文本右侧添加另一个文本视图。
步骤6
打开"Joshua Tree National Park"的属性检查器,然后选择Embed in hstack
。
步骤7
更改文本为"California",然后将字体设置为"subheadline"。
/// ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack {
Text("Joshua Tree National Park")
.font(.subheadline)
/// "步骤7: 和上一Text一同装进HStack,并设置文本和字体"
Text("California")
.font(.subheadline)
}
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
复制代码
预览: ⬇️
步骤8
让视图布局在整个屏幕宽度上,插入Spacer()
,如下。
默认情况下,文本内容宽度决定文本视图区域,使用
Spacer()
可撑开当前Stack
内所有视图,使View们充分利用该Stack
的所有空间。
/// ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer() // "步骤8: 添加占位空间"
Text("California")
.font(.subheadline)
}
}
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
复制代码
预览: ⬇️
步骤9
最后,使用.padding()
方法给整个VStack
一点喘息的空间。
/// ContentView.swift
import SwiftUI
struct ContentView: View {
var body: some View {
VStack(alignment: .leading) {
Text("Turtle Rock")
.font(.title)
HStack {
Text("Joshua Tree National Park")
.font(.subheadline)
Spacer()
Text("California")
.font(.subheadline)
}
}
.padding() // "步骤9: 设置默认内边距,使得VStack内部视图起始点不再死死地贴近边缘"
}
}
struct ContentView_Preview: PreviewProvider {
static var previews: some View {
ContentView()
}
}
复制代码
预览: ⬇️
四、创建自定义图像
设置好地标名称和详情的各种文本视图后,接下来来张图意思一下。
不再在上面文件中添加新代码,我们寻另一处实现带有遮罩、边框和阴影效果的图片 View。
步骤1
在项目的资源文件夹中找到"turtlerock.png",将其拖到"Resources"目录中的"AppIcon"位置。
接下来,为自定义图像视图创建一个新的".swift"文件。
步骤2
选择File > New > File
打开模板选择器,选择User Interface
分类下的SwiftUI View
,然后单击Next
。将文件命名为"CircleImage.swift",然后单击Create
完成创建。
您可以插入图像并修改其显示以匹配所需的设计。
步骤3
使用Image(_:)
方法初始化图像,替换掉默认的Text
视图。
/// CircleImage.swift
import SwiftUI
struct CircleImage: View {
var body: some View {
/// "步骤3"
Image("turtlerock")
}
}
struct CircleImage_Preview: PreviewProvider {
static var previews: some View {
CircleImage()
}
}
复制代码
预览: ⬇️
步骤4
使用.clipShape(Circle())
方法将图片裁成圆形。
Circle(),作为圆圈可以用作遮罩,也可以在圈内填充颜色来用作单独的圆形视图。
/// CircleImage.swift
import SwiftUI
struct CircleImage: View {
var body: some View {
Image("turtlerock")
/// "步骤4: 搞成圆的"
.clipShape(Circle())
}
}
struct CircleImage_Preview: PreviewProvider {
static var previews: some View {
CircleImage()
}
}
复制代码
预览: ⬇️
步骤5
创建一个灰色的圆圈作为边框,然后将其盖在上面的圆形图片上。
/// CircleImage.swift
import SwiftUI
struct CircleImage: View {
var body: some View {
Image("turtlerock")
.clipShape(Circle())
/// "步骤5: 盖一个圆圈,灰色的,宽度为4"
.overlay(
Circle().stroke(Color.gray, lineWidth: 4))
}
}
struct CircleImage_Preview: PreviewProvider {
static var previews: some View {
CircleImage()
}
}
复制代码
预览: ⬇️
步骤6
接下来,添加半径为10点的阴影。
/// CircleImage.swift
import SwiftUI
struct CircleImage: View {
var body: some View {
Image("turtlerock")
.clipShape(Circle())
.overlay(
Circle().stroke(Color.gray, lineWidth: 4))
/// "步骤6: 设置阴影"
.shadow(radius: 10)
}
}
struct CircleImage_Preview: PreviewProvider {
static var previews: some View {
CircleImage()
}
}
复制代码
预览: ⬇️
步骤7
将步骤5里的边框颜色切换为白色,收工。
/// CircleImage.swift
import SwiftUI
struct CircleImage: View {
var body: some View {
Image("turtlerock")
.clipShape(Circle())
.overlay(
Circle().stroke(Color.white, lineWidth: 4)) // "步骤7: 切换为白色"
.shadow(radius: 10)
}
}
struct CircleImage_Preview: PreviewProvider {
static var previews: some View {
CircleImage()
}
}
复制代码
预览: ⬇️