前言:
本章节通过TabView
,Gradient
,Color set
,.infinity
等,多个SwiftUI page 实现app首页轮播效果,首屏轮播交互为大部分App都会有的场景,看完本章帮助同学们上手开发属于自己的Carousel
首屏轮播最终效果
创建WelcomePage页
首先创建项目:OnboardingFlow(点击查看如何创建ios应用)
创建项目成功后,在导航栏点击项目右键创建New File
// WelcomePage
import SwiftUI
struct WelcomePage: View {
var body: some View {
Text("Hello, World!")
}
}
#Preview {
WelcomePage()
}
写入欢迎文案
// WelcomePage
var body: some View {
+ VStack {
- Text("Hello, World!")
+ Text("Welcome to MyApp")
+ .font(.title) //字体大小
+ .fontWeight(.semibold) // 加粗
+ Text("Description text").font(.title2)
+ }
}
添加.border
属性我们能更好调试UI样式
// WelcomePage
VStack {
Text("Welcome to MyApp")
.font(.title) //字体大小
.fontWeight(.semibold) // 加粗
+ .border(.black, width: 1.5)
Text("Description text").font(.title2)
+ .border(.black, width: 1.5)
}
+ .border(.orange, width: 1.5)
+ .padding()
+ .border(.purple, width: 1.5)
为了显示欢迎的icon图,这里添加个圆角frame RoundedRectangle
// WelcomePage
VStack {
+ RoundedRectangle(cornerRadius: 30) // 圆角30
+ .frame(width: 150, height: 150) // 宽高 150
+ .foregroundStyle(.tint) // 背景蓝色
....
Padding设置标题边距
现在看效果标题位置有点拥挤,可以给标题添加边距 .padding(.top)
// WelcomePage
VStack {
Text("Welcome to MyApp")
.font(.title) //字体大小
.fontWeight(.semibold) // 加粗
+ .padding(.top) // 添加边距
.border(.black, width: 1.5)
这样看效果是不是更好了呢?也可以单独添加不同方向的边距,我们可以在XCode
查看Padding
文档
点击EdgeInsets
查看具体参数:
有兴趣的同学可以试着使用
ZStack 嵌入字体图标
现在需要再蓝色背景添加个icon,需要使用到ZStack
它可以使 views
叠加在另一个上
// WelcomePage
VStack {
+ ZStack {
RoundedRectangle(cornerRadius: 30)
.frame(width: 150, height: 150)
.foregroundStyle(.tint)
+ Image(systemName: "figure.2.and.child.holdinghands") // 添加个icon 图片
+ .font(.system(size: 70)) // icon size 70
+ .foregroundStyle(.white) // icon 背景白色
+ }
最后把之前用来调试的边框.border
去掉
大致完成了欢迎页的第一张图
创建FeaturesPage
创建功能介绍主页
// FeaturesPage
import SwiftUI
struct FeaturesPage: View {
var body: some View {
VStack {
Text("Features")
.font(.title)
.fontWeight(.semibold)
}
.padding()
}
}
#Preview {
FeaturesPage()
}
创建FeatureCard
创建功能介绍卡片,自定义传参iconName
,description
// FeatureCard
import SwiftUI
struct FeatureCard: View {
let iconName: String
let description: String
var body: some View {
HStack { // 水平方向
Image(systemName: iconName).font(.largeTitle)
Text(description)
}
.padding()
.background(.tint, in: RoundedRectangle(cornerRadius: 12)) // card背景颜色
.foregroundStyle(.white) // card 字体颜色
}
}
#Preview {
// 调用FeatureCard传入参数
FeatureCard(
iconName: "person.2.crop.square.stack.fill",
description: "A multiline description about a feature paired with the image on the left.")
}
这里使用到了struct
自定义传参,在ios入门实例(二)中有提到
FeaturesPage 中调用FeatureCard
在FeaturesPage页面中自定义传参调用FeatureCard
// FeaturesPage
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",
+ description: "A multiline description about a feature paired with the +image on the left.")
}
.padding()
}
}
#Preview {
FeaturesPage()
}
再新增个FeatureCard
// FeaturesPage
FeatureCard(
iconName: "person.2.crop.square.stack.fill",
description: "A multiline description about a feature paired with the image on the left.")
+ FeatureCard(iconName: "quote.bubble.fill", description: "Short summary")
由效果图可以看到第二个 FeatureCard width方法没有填充满,可以使用Spacer
进行拉伸水平方向
// FeatureCard
...
HStack { // 水平方向
Image(systemName: iconName).font(.largeTitle)
Text(description)
+ Spacer()
...
虽然填充好了但icon图宽度不一致通过设置 .frame
来解决
// FeatureCard
...
HStack { // 水平方向
Image(systemName: iconName).font(.largeTitle)
+ .frame(width: 50)
+ .padding(.trailing, 10)
...
TabView 滑动切换Page
修改主入口ContentView.swift
代码
// ContentView.swift
import SwiftUI struct ContentView: View {
var body: some View {
+ TabView {
+ WelcomePage()
+ FeaturesPage()
+ }
+ .tabViewStyle(.page) // 左右切换
}
}
#Preview {
ContentView()
}
TabView
左右切换是有spot
样式,由于与背景都为白色所以看不出来,接下来开始设置背景
配置主题颜色&&设置背景
通过配置主题用来设置Page背景颜色,丰富轮播图视觉
配置主题GradientTop
颜色步骤:
创建成功后点击Any Appearance
白色背景块开始配置,色值:Red 0.852
, Green 0.646
, Blue 0.847
同样步骤配置GradientBottom
,色值:Red 0.954
, Green 0.529
, Blue 0.385
主题颜色配置好后,我们可以开始配置ContentView.swift
背景颜色了,全局声明主题颜色
// ContentView.swift
+ // 全局声明主题颜色
+ let gradientColors: [Color] =
+ [
+ .gradientTop,
+ .gradientBottom
+ ]
....
TabView {
WelcomePage()
FeaturesPage()
}
+ .background(Gradient(colors: gradientColors))
FeaturesPage 样式微调
切换到FeaturesPage代码,Preview
预览中添加全局主题颜色
// FeaturesPage
#Preview {
FeaturesPage()
+ .background(Gradient(colors: gradientColors))
+ .foregroundStyle(.white)
}
从样式中看主体内容没有撑满全屏,需要设置 maxHeight 为 .infinity
// FeaturesPage
#Preview {
FeaturesPage()
+ .frame(maxHeight: .infinity)
.background(Gradient(colors: gradientColors))
.foregroundStyle(.white)
}
接下来padding
,VStack
,Spacer
微调
// FeaturesPage
import SwiftUI
struct FeaturesPage: View {
var body: some View {
- VStack {
+ VStack(spacing: 30) {
Text("Features")
.font(.title)
.fontWeight(.semibold)
.padding(.bottom)
+ .padding(.top, 100)// 顶部边距 100
FeatureCard(
iconName: "person.2.crop.square.stack.fill",
description: "A multiline description about a feature paired with the image on the left.")
+ Spacer() // 填充空白使内容往顶部靠拢
}
.padding()
}
}
#Preview {
FeaturesPage()
}
FeaturesCard 样式微调
主要使用opacity
,brightness
增加透明效果
// FeatureCard
var body: some View {
...
.background(
- .tint, in: RoundedRectangle(cornerRadius: 12)
+ RoundedRectangle(cornerRadius: 12) // 圆角
+ .foregroundStyle(.tint) // 背景
+ .opacity(0.25) // 透明度
+ .brightness(-0.4) // 亮度调整
)
.foregroundStyle(.white) // card 字体颜色
}
brightness
属性,它允许你获取或设置屏幕的亮度。这个值的范围是 0.0(最暗)到 1.0(最亮)。
最终效果: