SwiftUI 全组件详解(iOS 端)
SwiftUI 是苹果推出的声明式 UI 框架,覆盖 iOS、macOS、watchOS 等多平台,下面是 iOS 端核心组件的分类详解,包含用法、核心属性和常见场景,基于最新 SwiftUI 5(iOS 18)适配。
一、基础视图组件
基础视图是构建 UI 的最小单元,用于展示文本、图片、图标等核心内容。
1. Text(文本)
作用:展示静态/动态文本,支持富文本、样式定制。 核心属性:
font(_:):设置字体(Font.title/Font.system(size:16, weight:.bold));foregroundStyle(_:):文本颜色(支持渐变);multilineTextAlignment(_:):对齐方式(.leading/.center/.trailing);lineLimit(_:):行数限制(nil表示无限制);truncationMode(_:):截断方式(.tail/.head/.middle)。
示例:
Text("Hello SwiftUI")
.font(.title)
.foregroundStyle(LinearGradient(colors: [.red, .blue], startPoint: .leading, endPoint: .trailing))
.padding()
2. Image(图片)
作用:展示本地/网络图片,支持缩放、裁剪、渲染模式。 核心属性:
resizable(capInsets:resizingMode:):自适应尺寸(必加,否则图片按原始尺寸显示);scaledToFit()/scaledToFill():适配方式(保持比例);clipShape(_:):裁剪形状(Circle()/RoundedRectangle(cornerRadius:10));renderingMode(_:):渲染模式(.original保留原图,.template作为模板色);asyncImage(url:):加载网络图片(iOS 15+)。
示例:
// 本地图片
Image("avatar")
.resizable()
.scaledToFit()
.frame(width: 100, height: 100)
.clipShape(Circle())
// 网络图片
AsyncImage(url: URL(string: "https://example.com/photo.jpg")) { phase in
switch phase {
case .empty: ProgressView() // 加载中
case .success(let image): image.resizable().scaledToFit()
case .failure: Image(systemName: "photo.badge.exclamationmark") // 加载失败
@unknown default: EmptyView()
}
}
.frame(width: 200, height: 200)
3. Image(systemName:)(SF Symbols 图标)
作用:使用苹果内置的 SF Symbols 图标库,支持自定义颜色/大小。 核心属性:
font(_:):设置图标大小(Font.system(size:24));foregroundStyle(_:):图标颜色;symbolVariant(_:):图标变体(.fill/.circle/.square);symbolRenderingMode(_:):渲染模式(.hierarchical/.palette)。
示例:
Image(systemName: "heart.fill")
.font(.system(size: 32))
.foregroundStyle(.red)
.symbolVariant(.circle)
4. Label(标签)
作用:组合图标+文本的复合视图(系统默认排版)。 核心属性:
init(_ title: String, systemImage: String):快捷创建(文本+SF 图标);labelStyle(_:):样式(.iconOnly/.titleOnly/.titleAndIcon/.automatic);titleSpacing(_:):图标与文本间距。
示例:
Label("设置", systemImage: "gear")
.labelStyle(.automatic)
.labelIconToTitleSpacing(8)
.foregroundStyle(.gray)
二、容器视图组件
容器视图用于布局和管理多个子视图,是构建复杂 UI 的核心。
1. VStack(垂直栈)
作用:垂直排列子视图,默认居中对齐。 核心属性:
init(alignment: HorizontalAlignment, spacing: CGFloat?, content:):对齐方式、子视图间距;spacing:子视图间距(默认系统自适应);alignment:水平对齐(.leading/.center/.trailing/.top等)。
示例:
VStack(alignment: .leading, spacing: 12) {
Text("标题")
.font(.headline)
Text("副标题")
.font(.subheadline)
.foregroundStyle(.gray)
}
.padding()
2. HStack(水平栈)
作用:水平排列子视图,默认居中对齐。 核心属性:
init(alignment: VerticalAlignment, spacing: CGFloat?, content:):垂直对齐、子视图间距;alignment:垂直对齐(.top/.center/.bottom/.firstTextBaseline等)。
示例:
HStack(alignment: .center, spacing: 8) {
Image(systemName: "bell")
Text("消息通知")
Spacer() // 推挤右侧视图到最右
Image(systemName: "chevron.right")
.foregroundStyle(.gray)
}
.padding(.horizontal)
3. ZStack(层级栈)
作用:重叠排列子视图,默认居中对齐。 核心属性:
init(alignment: Alignment, content:):对齐方式(.topLeading/.center/.bottomTrailing等);zIndex(_:):子视图层级(数值越大越上层)。
示例:
ZStack(alignment: .bottomTrailing) {
Image("background")
.resizable()
.scaledToFill()
.frame(width: 200, height: 200)
Text("标签")
.padding(4)
.background(Color.red)
.foregroundStyle(.white)
.cornerRadius(4)
.padding(8)
}
.clipShape(RoundedRectangle(cornerRadius: 10))
4. List(列表)
作用:滚动列表,支持单行/分组/可编辑,替代 UIKit 的 UITableView。 核心属性:
listStyle(_:):列表样式(.plain/.grouped/.insetGrouped/.sidebar);onDelete(perform:):删除操作(需配合ForEach);onMove(perform:):移动操作(需配合EditButton);selection(_:):选中项绑定(iOS 14+)。
示例:
struct ListDemo: View {
@State private var items = ["苹果", "香蕉", "橙子"]
@State private var editing = false
var body: some View {
NavigationStack {
List {
ForEach(items, id: \.self) { item in
Text(item)
}
.onDelete { indexSet in
items.remove(atOffsets: indexSet)
}
.onMove { source, destination in
items.move(fromOffsets: source, toOffset: destination)
}
}
.listStyle(.insetGrouped)
.navigationTitle("水果列表")
.toolbar {
EditButton() // 编辑按钮
}
}
}
}
5. ScrollView(滚动视图)
作用:可滚动的容器,支持垂直/水平滚动,无默认单元格复用(区别于 List)。 核心属性:
init(.vertical/.horizontal, showsIndicators: Bool, content:):滚动方向、是否显示滚动条;scrollIndicators(_:):滚动条样式(.hidden/.automatic/.visible);scrollDismissesKeyboard(_:):滚动时关闭键盘(.immediately/.interactively)。
示例:
ScrollView(.vertical, showsIndicators: false) {
VStack(spacing: 20) {
ForEach(1...20, id: \.self) { i in
Text("滚动项 \(i)")
.frame(maxWidth: .infinity)
.padding()
.background(Color.gray.opacity(0.1))
.cornerRadius(8)
}
}
.padding()
}
6. LazyVStack/LazyHStack(懒加载栈)
作用:类似 VStack/HStack,但仅渲染可视区域内的子视图,适合长列表(性能优化)。 核心属性:
pinnedViews(_:):固定视图(.sectionHeaders/.sectionFooters);- 其他属性与普通栈一致。
示例:
ScrollView {
LazyVStack(spacing: 10, pinnedViews: .sectionHeaders) {
Section(header: Text("头部固定").font(.title).background(Color.white)) {
ForEach(1...100, id: \.self) { i in
Text("懒加载项 \(i)")
.frame(height: 50)
}
}
}
}
7. Grid(网格)
作用:二维网格布局(iOS 16+),替代手动嵌套 HStack/VStack。 核心组件:
GridRow:网格行;GridItem:网格列配置(.flexible()/.adaptive(minimum:)/.fixed());alignment:单元格对齐方式。
示例:
Grid(alignment: .center, horizontalSpacing: 8, verticalSpacing: 8) {
GridRow {
Text("1")
.frame(maxWidth: .infinity)
.background(Color.gray.opacity(0.1))
Text("2")
.frame(maxWidth: .infinity)
.background(Color.gray.opacity(0.1))
}
GridRow {
Text("3")
.frame(maxWidth: .infinity)
.background(Color.gray.opacity(0.1))
Text("4")
.frame(maxWidth: .infinity)
.background(Color.gray.opacity(0.1))
}
}
.padding()
8. Group(分组)
作用:分组子视图,无视觉效果,仅用于拆分代码或突破 10 个子视图限制。 示例:
VStack {
Group {
Text("1")
Text("2")
Text("3")
}
Group {
Text("4")
Text("5")
}
}
三、交互控件组件
用于响应用户操作(点击、输入、选择等)的交互型组件。
1. Button(按钮)
作用:响应点击操作,支持自定义样式。 核心属性:
init(action: @escaping () -> Void, label: () -> Label):点击事件、按钮内容;buttonStyle(_:):样式(.plain/.bordered/.borderedProminent/.borderless);tint(_:):按钮主色调;disabled(_:):是否禁用。
示例:
Button(action: {
print("按钮点击")
}) {
HStack {
Image(systemName: "paperplane")
Text("提交")
}
}
.buttonStyle(.borderedProminent)
.tint(.blue)
.disabled(false)
.padding()
2. Toggle(开关)
作用:布尔值切换控件(类似 UISwitch)。 核心属性:
init(isOn: Binding<Bool>, label:):绑定布尔值、标签;toggleStyle(_:):样式(.switch/.button/.checkbox);tint(_:):开启状态颜色。
示例:
struct ToggleDemo: View {
@State private var isOn = false
var body: some View {
Toggle(isOn: $isOn) {
Text("开启通知")
}
.toggleStyle(.switch)
.tint(.green)
.padding()
}
}
3. TextField(单行输入框)
作用:单行文本输入,支持键盘类型、占位符等。 核心属性:
init(_ prompt: String, text: Binding<String>):占位符、绑定文本;keyboardType(_:):键盘类型(.numberPad/.emailAddress/.default);autocapitalization(_:):自动大写(.none/.words);disableAutocorrection(_:):禁用自动纠错;onCommit(perform:):回车触发事件。
示例:
struct TextFieldDemo: View {
@State private var text = ""
var body: some View {
TextField("请输入用户名", text: $text)
.keyboardType(.default)
.autocapitalization(.none)
.disableAutocorrection(true)
.padding()
.background(Color.gray.opacity(0.1))
.cornerRadius(8)
.padding(.horizontal)
}
}
4. TextEditor(多行文本编辑器)
作用:多行文本输入(类似 UITextView)。 核心属性:
init(text: Binding<String>):绑定文本;foregroundStyle(_:):文本颜色;font(_:):字体;scrollContentBackground(_:):是否显示滚动背景(.hidden可去除默认白色背景)。
示例:
struct TextEditorDemo: View {
@State private var text = ""
var body: some View {
TextEditor(text: $text)
.font(.body)
.foregroundStyle(.black)
.scrollContentBackground(.hidden)
.background(Color.gray.opacity(0.1))
.frame(height: 150)
.padding()
}
}
5. Slider(滑块)
作用:数值选择滑块(范围值)。 核心属性:
init(value: Binding<Double>, in range: ClosedRange<Double>, step: Double):绑定值、范围、步长;tint(_:):滑块进度颜色;onChange(of: value) { newValue in }:值变化监听。
示例:
struct SliderDemo: View {
@State private var progress = 0.0
var body: some View {
VStack {
Slider(value: $progress, in: 0...100, step: 1)
.tint(.orange)
.padding()
Text("进度:\(Int(progress))%")
}
}
}
6. Picker(选择器)
作用:下拉/滚轮选择器,支持多类型数据源。 核心属性:
init(selection: Binding<Value>, label: Label, content:):选中值绑定、标签;pickerStyle(_:):样式(.menu/.wheel/.segmented/.inline);ForEach:数据源遍历。
示例:
struct PickerDemo: View {
@State private var selectedFruit = "苹果"
let fruits = ["苹果", "香蕉", "橙子", "葡萄"]
var body: some View {
Picker(selection: $selectedFruit, label: Text("选择水果")) {
ForEach(fruits, id: \.self) {
Text($0)
}
}
.pickerStyle(.menu) // 下拉菜单样式
.padding()
}
}
7. DatePicker(日期选择器)
作用:日期/时间选择器(类似 UIDatePicker)。 核心属性:
init(_ label: String, selection: Binding<Date>, displayedComponents:):标签、绑定日期、显示组件(.date/.time/.dateAndTime);datePickerStyle(_:):样式(.compact/.wheel/.graphical);range(_:):可选日期范围。
示例:
struct DatePickerDemo: View {
@State private var selectedDate = Date()
var body: some View {
DatePicker("选择日期", selection: $selectedDate, displayedComponents: .date)
.datePickerStyle(.compact)
.padding()
}
}
8. Stepper(步进器)
作用:增减数值的控件(+/- 按钮)。 核心属性:
init(_ label: String, value: Binding<Value>, in range: ClosedRange<Value>, step: Value):标签、绑定值、范围、步长;onIncrement(perform:):增加触发事件;onDecrement(perform:):减少触发事件。
示例:
struct StepperDemo: View {
@State private var count = 0
var body: some View {
Stepper("数量:\(count)", value: $count, in: 0...10, step: 1)
.padding()
}
}
四、导航与页面组件
用于页面跳转、导航栏管理、模态弹窗等场景。
1. NavigationStack(导航栈,iOS 16+)
作用:替代旧版 NavigationView,实现页面层级导航。
核心属性:
init(path: Binding<NavigationPath>, root:):导航路径绑定(支持任意可哈希类型);navigationTitle(_:):导航栏标题;navigationBarTitleDisplayMode(_:):标题显示模式(.large/.inline/.automatic);toolbar(content:):导航栏工具栏(按钮、菜单);navigationDestination(for:destination:):目标页面映射。
示例:
struct NavigationDemo: View {
@State private var path = NavigationPath()
let fruits = ["苹果", "香蕉", "橙子"]
var body: some View {
NavigationStack(path: $path) {
List(fruits, id: \.self) { fruit in
NavigationLink(value: fruit) {
Text(fruit)
}
}
.navigationTitle("水果列表")
.navigationDestination(for: String.self) { fruit in
Text("你选择了:\(fruit)")
.navigationTitle(fruit)
}
.toolbar {
Button("返回首页") {
path.removeLast(path.count)
}
}
}
}
}
2. Sheet(模态弹窗)
作用:弹出模态视图(从底部滑入)。 核心属性:
sheet(isPresented: Binding<Bool>, onDismiss: (() -> Void)?, content:):显示状态绑定、关闭回调、弹窗内容;presentationDetents(_:):弹窗高度(.height(200)/.medium/.large,iOS 16+);presentationDragIndicator(_:):拖拽指示器(.visible/.hidden,iOS 16+)。
示例:
struct SheetDemo: View {
@State private var showSheet = false
var body: some View {
Button("打开弹窗") {
showSheet = true
}
.sheet(isPresented: $showSheet) {
Text("模态弹窗内容")
.presentationDetents([.medium, .large])
.presentationDragIndicator(.visible)
}
}
}
3. Alert(警告弹窗)
作用:系统样式的警告弹窗(含标题、按钮)。 核心属性:
alert(_: isPresented: actions: message:):标题、显示状态、按钮组、消息内容;ButtonRole:按钮角色(.cancel/.destructive/.none)。
示例:
struct AlertDemo: View {
@State private var showAlert = false
var body: some View {
Button("显示警告") {
showAlert = true
}
.alert("提示", isPresented: $showAlert) {
Button("取消", role: .cancel) {}
Button("确认", role: .none) {}
} message: {
Text("确定要执行此操作吗?")
}
}
}
4. Popover(弹出框,iOS 14+)
作用:从指定位置弹出的气泡视图。 核心属性:
popover(isPresented: attachmentAnchor: arrowEdge: content:):显示状态、锚点、箭头方向、内容。
示例:
struct PopoverDemo: View {
@State private var showPopover = false
var body: some View {
Button("弹出菜单") {
showPopover = true
}
.popover(isPresented: $showPopover, attachmentAnchor: .point(.topTrailing), arrowEdge: .top) {
VStack {
Text("选项1")
Text("选项2")
Text("选项3")
}
.padding()
.frame(width: 150)
}
}
}
五、视觉装饰组件
用于增强 UI 视觉效果的装饰性组件。
1. Divider(分割线)
作用:水平分割线,用于分隔视图。 核心属性:
foregroundStyle(_:):分割线颜色;frame(height:):分割线高度。
示例:
VStack {
Text("上部分")
Divider()
.foregroundStyle(.gray.opacity(0.3))
.frame(height: 1)
Text("下部分")
}
.padding()
2. Spacer(空白填充)
作用:占据剩余空间,用于推挤子视图到指定位置。 核心属性:
minLength(_:):最小长度(默认 0)。
示例:
HStack {
Text("左侧")
Spacer(minLength: 20)
Text("右侧")
}
.padding()
3. Color(颜色视图)
作用:纯色背景/装饰,可作为视图使用。 核心属性:
opacity(_:):透明度;gradient(_:):渐变(LinearGradient/RadialGradient/AngularGradient);frame():尺寸(默认填充父视图)。
示例:
Color.blue
.opacity(0.5)
.frame(height: 100)
.cornerRadius(10)
.padding()
4. RoundedRectangle/Circle/Capsule(形状视图)
作用:基础形状,用于背景、裁剪、装饰。 核心属性:
fill(_:):填充颜色/渐变;stroke(_:lineWidth:):描边;cornerRadius(_:)(仅 RoundedRectangle):圆角。
示例:
RoundedRectangle(cornerRadius: 12)
.fill(LinearGradient(colors: [.purple, .pink], startPoint: .leading, endPoint: .trailing))
.stroke(Color.white, lineWidth: 2)
.frame(width: 200, height: 100)
六、高级组件(iOS 14+)
1. ProgressView(进度条)
作用:展示加载进度(确定/不确定)。 核心属性:
init(value: Binding<Double>?, total: Double = 1.0):进度值、总进度;progressViewStyle(_:):样式(.linear/.circular/.automatic);tint(_:):进度颜色。
示例:
struct ProgressViewDemo: View {
@State private var progress = 0.5
var body: some View {
VStack {
// 确定进度
ProgressView(value: progress, total: 1.0)
.progressViewStyle(.linear)
.tint(.blue)
.padding()
// 不确定进度(加载中)
ProgressView()
.progressViewStyle(.circular)
.tint(.orange)
}
}
}
2. Menu(菜单)
作用:下拉菜单(点击展开选项)。 核心属性:
init(content: label:):菜单内容、触发标签;menuStyle(_:):样式(.borderlessButton/.contextMenu);Button(role:):菜单选项(支持取消/销毁角色)。
示例:
Menu {
Button("编辑", action: {})
Button("删除", role: .destructive, action: {})
Button("分享", action: {})
Divider()
Button("取消", role: .cancel, action: {})
} label: {
Label("更多操作", systemImage: "ellipsis.circle")
}
3. TabView(标签页)
作用:底部/顶部标签页切换(类似 UITabBarController)。 核心属性:
tabViewStyle(_:):样式(.page/.tabBar);tabItem { Label(...) }:标签项内容;tag(_:):标签标识(配合选中绑定);selection(_:):选中标签绑定。
示例:
struct TabViewDemo: View {
@State private var selectedTab = 0
var body: some View {
TabView(selection: $selectedTab) {
Text("首页")
.tabItem {
Label("首页", systemImage: "house")
}
.tag(0)
Text("消息")
.tabItem {
Label("消息", systemImage: "bell")
}
.tag(1)
Text("我的")
.tabItem {
Label("我的", systemImage: "person")
}
.tag(2)
}
.tint(.blue)
}
}
七、关键注意事项
- 版本适配:部分组件(如
NavigationStack、Grid)仅支持 iOS 16+,低版本需用NavigationView等兼容方案; - 性能优化:长列表优先用
List/LazyVStack,避免普通VStack导致的卡顿; - 状态管理:所有交互组件需配合
@State/@Binding/@ObservedObject等状态属性; - 样式定制:可通过
ViewModifier封装自定义样式,减少重复代码; - 多平台兼容:部分组件(如
SidebarListStyle)仅在 iPad/macOS 生效,iOS 需适配。
以上覆盖了 SwiftUI 核心组件,实际开发中可结合苹果官方文档(SwiftUI 官方文档)和 SF Symbols 库扩展使用。