本课程将探索三种基本的堆栈,它们分别用于水平排列视图、垂直排列视图以及将视图分层堆叠。
学习内容汇总:
- 使用类型推断减少代码
- 使用边框调试布局问题
- 使用框架调整元素大小
- 使用三种类型的堆栈——
VStack、HStack和ZStack——创建复杂界面 - 使用间距控制栈中内容的排列
- 使用分页标签视图在视图之间导航
- 资源库中的自定义颜色集
如果字符串长到要换行,可以在Text下面用multilineTextAlignmnent(.)来指定换行方式
Text("现在你可以走了!现在你可以走了!现在你可以走了")
.multilineTextAlignment(.center)中间对齐
.multilineTextAlignment(.leading)左对齐
**.multilineTextAlignment(.trailing)**右对齐
添加边框
使用.border(.black, width: 1.5)
通过使用形状和 SF Symbol 添加图形来完成欢迎页面。
首先添加一个形状。
添加圆角矩形:RoundedRectangle(cornerRadius: 30)
RoundedRectangle(cornerRadius: 30) .frame(width: 150, height: 150) .foregroundStyle(.tint)//.tint代表应用的强调色 //默认扩充整个空间,因为无理想大小Text("欢迎您来") .font(.title)//突出显示,这里的Font可以不写,系统会自动推断为Font .fontWeight(.semibold) .fontWidth(.compressed) .padding(.top)//在添加边框之前添加内边距,将填充限制在顶部.top,底部.bottom 右边.trailing 左边.leading // .padding(.bottom)ZStack用于将视图一个叠一个地排列。
放大系统图标,移除边框
看来边框是为了让人知道现在在写什么东西的...
创建功能页面
锁定某一页面,这个小图钉
Spacer()的效果:从左到右
在栈的末尾添加一个 Spacer。这将使卡片的其他内容移至前沿,并使卡片占据整个屏幕宽度。
Frame(width: 50)通过frame使图标占据相同宽度
FeatureCard
import SwiftUI struct FeatureCard: View { let iconName: String let descprition: String var body: some View { HStack { Image(systemName: iconName) .font(.largeTitle) .frame(width: 50)//通过frame使图标占据相同宽度 .padding(.trailing, 10)//距离右边框的内边距为10,调大就留白越多 Text(descprition)//提示说明参数 Spacer() } .padding()//在背景修饰符之前留出一些空间 .background(.tint, in: RoundedRectangle(cornerRadius: 12)) .foregroundStyle(.white) } } #Preview {//修复这里的实例 FeatureCard(iconName: "person.2.crop.square.stack.fill", descprition: "A multiline description about a feature a paired with the image on the left.") } //需要创建实例,因为结构体没有实例。FeaturedPage
import SwiftUI struct FeaturesPage: View { var body: some View { VStack { Text("Features") .font(.title) .fontWeight(.semibold) .padding(.bottom) FeatureCard(iconName: "person.2.crop.square.stack.fill", descprition: "A multiline description about a feature paired with the image on the left.") FeatureCard(iconName: "quote.bubble.fill", descprition: "Short summary")//一张更简洁的卡片,创建FeatureCard结构体实例 } .padding() } } #Preview { FeaturesPage() }使用TabView组合屏幕:让用户在页面之间滑动
Tab包含多个子视图,但不会一次性显示全部
默认的TabView会在屏幕底部显示标签页,点击标签页就会显示对应视图。可以使用.tabViewStyle来修改
.page标签允许左右滑动以切换视图
// // ContentView.swift // OnboardingFlow // // Created by sakiko on 2026/4/22. // import SwiftUI struct ContentView: View { var body: some View { TabView {//TabView,让用户在页面之间滑动 WelcomePage() FeaturesPage() } .tabViewStyle(.page)//就是这 } } #Preview { ContentView() }在资源库中定义颜色
左侧的Assets
检查器:choosing View > Inspectors > Show Inspector.
这里选择none,相同颜色应用于浅色和深色外观。
然后在右边创建颜色
声明一个用于渐变颜色的全局属性
// ContentView.swift // OnboardingFlow // // Created by sakiko on 2026/4/22. // import SwiftUI //声明一个用于渐变颜色的全局属性 let gradientColors: [Color] = [ .gradientTop, .gradientBottom ]//这是全局属性,在所有代码里可见然后把渐变色应用到背景里
struct ContentView: View { var body: some View { TabView {//TabView,让用户在页面之间滑动 WelcomePage() FeaturesPage() } .background(Gradient(colors: gradientColors)) .tabViewStyle(.page) } }这是ContentView里,在ContentView中控制其他视图
struct ContentView: View { var body: some View { TabView {//TabView,让用户在页面之间滑动 WelcomePage() FeaturesPage() } .background(Gradient(colors: gradientColors)) .tabViewStyle(.page) .foregroundStyle(.white)//所有视图都适用(WelcomPage和FeaturesPage) //通过上面这一行! } }修改系统色(AccentColor)
添加一个有透明度的矩形,覆盖在背景上,实现以下操作:
创建一张带圆角的背景卡片
创建一个高度无限的面板
控制透明度
忽略上下布局
// FeaturesPage.swift // OnboardingFlow // // Created by sakiko on 2026/4/23. // import SwiftUI struct FeaturesPage: View { var body: some View { VStack(spacing: 30) {//通过设置spacing属性,控制VStack 中每个子视图之间的垂直间距 Text("Features") .font(.title) .fontWeight(.semibold) .padding(.bottom) .foregroundStyle(.black) .padding(.top, 100)//为了避免紧贴,还是得有一些内边距 FeatureCard(iconName: "person.2.crop.square.stack.fill", descprition: "A multiline description about a feature paired with the image on the left.") FeatureCard(iconName: "quote.bubble.fill", descprition: "Short summary")//一张更简洁的卡片,创建FeatureCard结构体实例 Spacer()//在最下面使用Spacer()来将内容推到顶部 } .padding() .background { RoundedRectangle(cornerRadius: 12) .foregroundStyle(.tint)//创建一张带圆角的背景卡片 .opacity(0.2)//控制透明度 }.ignoresSafeArea()//忽略上下布局,以后再说 } } #Preview { FeaturesPage() .frame(maxHeight: .infinity)//创建一个高度无限的面板 .background(Gradient(colors: gradientColors)) .foregroundStyle(.white) }最终效果大概就是这样
练习:
1.调整应用的设计。运用你学到的所有技巧,如内边距、间距和栈布局。
2.为引导流程添加第三页。
3.更改应用的主题色。更新两种渐变颜色或添加第三种。尝试调整不同的不透明度和亮度,使功能卡片彼此区分。
import SwiftUI struct Page_New: View { var body: some View { VStack(){ Text("这是第三页") .fontWeight(.semibold) .font(.title) .foregroundStyle(.black) .shadow(radius: 5) .padding(.top, 50) .frame(maxWidth: .infinity, alignment: .leading) .padding(.bottom, 25) //为了避免紧贴,还是得有一些内边距 FeatureCard(iconName: "person.2.crop.square.stack.fill", descprition: "这里是第三页,感谢您的观看。现在你可以走了,886!") FeatureCard(iconName: "quote.bubble.fill", descprition: "想吐槽我?但是没有机会") Spacer() } .padding() .background { RoundedRectangle(cornerRadius: 12) .foregroundStyle(.blue)//创建一张带圆角的背景卡片 .opacity(0.3)//控制透明度 }.ignoresSafeArea()//忽略上下布局,以后再说 } } #Preview { Page_New()//适用ContentView设定的背景色 .frame(maxHeight: .infinity) .frame(maxWidth: .infinity) .background(Gradient(colors: gradientColors)) .foregroundStyle(.white) }练习的效果: