SwiftUI 常用基础组件与修饰符笔记

整理一些 SwiftUI 入门常用组件和对应修饰符的笔记,以及一些参考文档地址等。

组件和修饰符库

  • 打开库:通过右上角的加号打开库,快捷键 Shift + Cmd + L
  • 组件与修饰符:
    • 选择 Show The View Library 查看所有 SwiftUI 组件及其简易用法,可以直接拖拽到代码中生成组件调用的代码。
    • 选择 Show The Modifiers Library 查看所有 SwiftUI 修饰符
  • 可以将组件拖拽到代码中合适的位置
  • 库里还有图标、图片、预定义的颜色等,都可以拖拽进代码

常用文档

常用组件

基础元素

  • Text("内容"):文本视图,用于显示静态文本,可以格式化数字、货币等
    • 显示内容是字符串,其他类型可转换为字符串:Text(String(num))Text("\(num)")
    • 直接传其他类型时,支持 format 属性进行转换,如 Text(num, format: .number)
  • Image("图名"):显示图像资源
    • 默认示例中包含系统图标 globe(来自 SF Symbols 系统图标库),无需额外引入资源。
    • 安装 SF Symbols 工具 查看图标,可在检查器调整其样式与动画,再复制对应的代码。
    • Image(systemName: "timelapse", variableValue: 0.2) 部分图标支持变量值,如 timelapse 支持传入进度值
    • 修饰符 .imageScale(.large) 用于调整图片的尺寸比例,特别是使用 SF Symbols )时,可以方便地设置小、中、大三种尺寸。
    • 修饰符 .resizable() 允许图片调整大小,使用自定义图片时, imageScale 需要和 resizable 一起用

布局

  • VStack:垂直堆栈布局容器,用于垂直排列子视图
    • alignment 参数:设置子视图的对齐方式。
    • spacing 参数:设置子视图之间的间距。
  • HStack:水平堆栈布局容器,用于水平排列子视图。
  • ZStack:视图层级叠加的核心布局容器,让子视图沿 Z 轴(垂直于屏幕方向)堆叠,形成多层视图结构。
    • 与 overlay/background 相比,是独立布局容器,适合复杂层级组合,可独立控制每层动画
  • Spacer():间隔视图,用于在布局中填充空白空间

列表与表单容器

  • List { ... }:可滚动列表容器,自动滚动,自动复用(高性能),支持滑动删除、移动、编辑模式,配合 Section 展示分组内容
    • 修饰符:.onDelete(perform: deleteIntakes) 添加删除功能
    • 修饰符:.swipeActions { ... } 添加滑动操作按钮
  • ScrollView { ... } 可滚动容器,内部不能嵌套 List
  • Form { ... }:表单容器,自动布局输入控件,支持分组或组件嵌套
  • Section("标题") { ... }:用于 FormList 分区,支持添加标题和页脚,内部嵌套组件

遍历数据

  • ForEach:遍历数据
    • 从 0 到 99:ForEach(0..<100) { number in ... }
    • ForEach(students, id: \.self) 遍历数组时,id 参数唯一标识,\.self 表示内容本身,适用于内容本身唯一的场景。
    • 遍历 SwiftData 模型时,框架自动提供唯一标识符,无需显式声明

表单组件

  • TextField("提示", text: $value):单行输入框
    • 输入任何类型的文本,将绑定值参数改为 value,并传入 format 参数进行转换。
      • 转换整数和浮点数,如 TextField("输入数字", value: $num, format: .number)
      • 转换货币:.currency(code: Locale.current.currency?.identifier ?? "USD")
    • 修饰符:.textFieldStyle(RoundedBorderTextFieldStyle()) 设置输入框样式。
    • .keyboardType() 修饰符,指定键盘类型,如 .numberPad(数字键盘)或 .decimalPad(支持小数点的数字键盘)。
    • .focused($amountIsFocused) 绑定焦点状态,变量需要是 @FocusState 的布尔值
  • Picker("选项", selection: $choice) { ... }:下拉选择器
    • 可嵌套 Text,并通过 ForEach 遍历选项。
    • .tag() 修饰符,指定选项值,如 ForEach 中使用 $0
    • .pickerStyle() 修饰符修改选择器样式:
      • .navigationLink 弹出全屏选择窗口,需在 NavigationStack 中使用。
      • .segmented 分段选择器
  • Toggle("启用提醒", isOn: $isReminderEnabled):开关控件,用于切换布尔值
  • DatePicker("时间选择器标签", selection: $binding, displayedComponents: .hourAndMinute):日期/时间选择器
    • 通过绑定变量获取选择的时间。
    • displayedComponents 参数指定显示的时间组件。

操作控件

  • Button("按钮") { ... }:按钮,触发操作
    • 修饰符:.buttonStyle(.borderedProminent) 设置按钮样式。
    • 通过 frame 和 border 控制的区域大小,并不是按钮本身的大小,无法覆盖按钮,点击空白处不会有反应,设置 buttonStyle 也只能看到真实的按钮区域有对应样式
    • 可通过 label 属性传入 Text 元素,去编写样式,把 frame 和 border 的样式放到 Text 中,这样按钮就能覆盖内部的整个占满宽度的 Text 元素
Button {
    print("Clicked!")
} label: {
    Text("Got it!")
        .padding(.all)
        .frame(maxWidth: .infinity)
        .background(RoundedRectangle(cornerRadius: 10).stroke())
}
  • Menu("添加饮水记录") { ... }:菜单控件,用于显示选项菜单
    • 内部可嵌套 Button

页面导航与弹窗

  • NavigationStack { ... }:导航容器(iOS 16+),避免内容滚动到灵动岛影响阅读
    • 修饰符:.navigationTitle("SwiftUI") 设置导航标题。
    • 修饰符:.navigationBarTitleDisplayMode(.inline) 设置标题显示模式(影响字体大小、位置)。
    • 修饰符:.toolbar { ... } 控制右上角按钮,可增加判断条件按需显示。
      • .toolbar 中配置 ToolbarItem(placement: .navigationBarTrailing) { ... },工具栏项组件可包含多个按钮。
      • placement 参数指定工具项的位置。
  • NavigationView { ... }:导航视图,用于创建带导航栏的界面。
  • NavigationLink("链接文本") { ... }:导航链接,用于在导航视图中创建可点击的导航项。
  • TabView { ... }:标签页容器,用于创建标签页界面。
    • 内部可嵌套 NavigationView { ... } 组件。
    • 修饰符:.tabItem { ... } 定义每个标签页底部标签项的标题和图标

数据展示组件

  • ProgressView(value: currentIntake, total: dailyGoal):进度条视图,用于显示进度。
    • 修饰符:.progressViewStyle(LinearProgressViewStyle()) 设置进度条样式。

常用修饰符

布局

  • .frame() 尺寸约束
    • .frame(width: 200, height: 100, alignment: .center) 设置视图高度、宽度、对齐方式,各项可单独设置
    • .frame(maxWidth: .infinity) 允许扩展到指定最大值,.infinity 表示视图最大可以扩展到无限宽,会被解释为"请给我所有可用空间",可撑满父容器宽度。
    • 在布局容器 VStack/HStack/ZStack 中,maxWidth/maxHeight 用于扩展空间,width/height 用于精确控制(若值无效则回退到默认尺寸)。
  • .padding() 添加内边距
    • .padding(.all) 设置所有方向的内边距
    • .padding(.horizontal) 添加水平的内边距
  • .position()
  • .offset()

外观

  • .foregroundColor(.red) 设置前景色(文本/图标颜色)
    • .foregroundColor(.accentColor) 设置为强调色
  • .border() 设置边框颜色
    • .border(Color.accentColor, width: 1) 设置边框颜色为强调色,宽度为 1
  • .tint(.blue) 设置视图的强调色(Accent Color) 或主题色
    • 用于 Button、TabBar、NavigationBar、Picker 等可交互控件,改变它们的默认颜色,会影响控件的高亮颜色、选中状态、边框颜色等
  • .background(Color.yellow) 设置背景视图或颜色
    • .background(RoundedRectangle(cornerRadius: 10).stroke()) 支持填充其他内容作为背景,如填充一个只有边框的圆角矩形,实现圆角矩形边框按钮
    • .background(.ultraThinMaterial) 将背景设置为透明的材质效果(可选择不同透明度, ultraThinMaterial 透明度最高)
  • .cornerRadius(20) 矩形类组件设置圆角
  • .shadow(color: .gray, radius: 5, x: 2, y: 2) 设置阴影
  • .accentColor(.black) 修改组件的强调色,默认是项目的强调色

文本

  • .font(.headline) 设置字体样式,对应的预设值包含字重、大小、字体的效果
    • .font(.system(size: 20, weight: .bold)) 单独设置字号、字重
  • .fontWeight(.bold) 单独设置字重,设置完 font 还需要微调时使用
  • .multilineTextAlignment(.center) 设置多行文本对齐方式
  • .lineLimit(2) 限制文本显示行数

交互

  • .opacity(0.5) 设置透明度
  • .disabled() 控件是否禁用,用于 Button 、 Picker 等可交互组件
    • .disabled(!isReminderEnabled) 根据条件禁用视图
  • .onTapGesture { ... } 点击事件,在大括号内编写点击等行为,可用于所有组件

动画与过渡

  • .animation(.easeInOut, value: isAnimating) 绑定值改变时,对应的属性变化触发动画
    • 需先创建可触发动画的视图,通过绑定值显示不同的样式或元素,比如 .background(isAnimating ? .blue : .red)
    • 监听改变 isAnimating 值时,可触发动画
    • .animation(.easeInOut(duration: 1), value: isAnimating) 指定动画时长
    • 列表渲染时可绑定数组,监视整个数组变化
  • .transition(.slide) 视图插入/移除的动画效果

视图上方叠加其他内容

可通过 .overlay 在视图上方叠加其他内容

Rectangle()
    .fill(Color.green)
    .frame(width: 200, height: 150)
    .overlay(
        Text("右上角"),
        alignment: .topTrailing // 文本定位在右上角
    )

在背景上再覆盖一个圆角矩形,还用 backgroud 叠上去效果比较奇怪,可使用 overlay 配合。

.background(.ultraThinMaterial)
.cornerRadius(50)
.overlay(RoundedRectangle(cornerRadius: 50).stroke())