当前位置: 首页 > news >正文

SwiftUI 常用控件分类与使用指南

目录

  • 一、文本显示控件
    • 1.1、Text - 基础文本
    • 1.2、Label - 图标+文本组合
    • 1.3、Link - 可点击链接
  • 二、图片显示控件
    • 2.1、Image - 图片显示
    • 2.2、AsyncImage - 异步加载图片
  • 三、按钮与交互控件
    • 3.1、Button - 基础按钮
    • 3.2、Menu - 下拉菜单
    • 3.3、ContextMenu - 长按菜单
  • 四、输入控件
    • 4.1、TextField - 单行文本输入
    • 4.1、TextEditor - 多行文本输入
    • 4.3、SecureField - 密码输入
  • 五、选择器控件
    • 5.1、Toggle - 开关
    • 5.2、Picker - 选择器
    • 5.3、Slider - 滑块
    • 5.4、Stepper - 步进器
    • 5.5、DatePicker - 日期选择
  • 六、列表与集合视图
    • 6.1、List - 列表视图
    • 6.2、ScrollView - 滚动视图
    • 6.3、Grid - 网格布局 (iOS 16+)
  • 七、进度指示器
    • 7.1、ProgressView - 进度条
    • 7.2、ActivityIndicator - 活动指示器 (UIKit桥接)
  • 八、容器视图
    • 8.1、VStack/HStack/ZStack - 基础布局
    • 8.2、LazyVStack/LazyHStack - 懒加载布局
    • 8.3、Group/GroupBox - 内容分组
  • 九、导航相关
    • 9.1、NavigationStack - 导航栈
    • 9.2、TabView - 标签页
  • 十、弹窗与提示
    • 10.1、Alert - 警告框
    • 10.2、Sheet - 底部表单
    • 10.3、Toast - 提示 (自定义实现)
  • 十一、形状与绘图
    • 11.1、基础形状
    • 11.2、自定义形状
  • 十二、高级控件
    • 12.1、Canvas - 绘图画布 (iOS 15+)
    • 12.2、Charts - 图表框架 (iOS 16+)
  • 最佳实践建议
    • 1、组合使用:通过组合简单控件创建复杂UI
    • 2、响应式设计:使用 `@ViewBuilder` 和条件语句
    • 3、平台适配
    • 4、性能优化

SwiftUI 提供了丰富的控件库,我将按功能分类介绍常用控件并提供使用示例:

一、文本显示控件

1.1、Text - 基础文本

Text("Hello SwiftUI!").font(.title)           // 字体.foregroundStyle(.blue) // 颜色.bold()                 // 加粗.italic()               // 斜体

1.2、Label - 图标+文本组合

Label("设置", systemImage: "gear").symbolRenderingMode(.multicolor) // 图标渲染模式Label("邮件", image: "custom_email") // 使用自定义图片

1.3、Link - 可点击链接

Link("访问苹果官网", destination: URL(string: "https://www.apple.com")!)

二、图片显示控件

2.1、Image - 图片显示

// 系统图标
Image(systemName: "heart.fill").resizable().aspectRatio(contentMode: .fit).frame(width: 50, height: 50).foregroundStyle(.red)// 资源图片
Image("profile_picture").resizable().scaledToFill().frame(width: 100, height: 100).clipShape(Circle()) // 圆形裁剪

2.2、AsyncImage - 异步加载图片

AsyncImage(url: URL(string: "https://example.com/image.jpg")) { image inimage.resizable()
} placeholder: {ProgressView()
}
.frame(width: 200, height: 200)
.clipShape(RoundedRectangle(cornerRadius: 10))

三、按钮与交互控件

3.1、Button - 基础按钮

Button("提交") {print("按钮被点击")
}
.buttonStyle(.borderedProminent)
.tint(.purple)

3.2、Menu - 下拉菜单

Menu("操作") {Button("复制", action: {})Button("粘贴", action: {})Menu("更多") {Button("保存", action: {})Button("删除", action: {})}
}

3.3、ContextMenu - 长按菜单

Image(systemName: "ellipsis.circle").contextMenu {Button("编辑", action: {})Button("分享", action: {})Button("删除", role: .destructive, action: {})}

四、输入控件

4.1、TextField - 单行文本输入

@State private var username = ""TextField("用户名", text: $username).textFieldStyle(.roundedBorder).autocorrectionDisabled() // 禁用自动修正.textInputAutocapitalization(.never) // 禁用首字母大写

4.1、TextEditor - 多行文本输入

@State private var bio = ""TextEditor(text: $bio).frame(height: 150).border(Color.gray, width: 1)

4.3、SecureField - 密码输入

@State private var password = ""SecureField("密码", text: $password).textFieldStyle(.roundedBorder)

五、选择器控件

5.1、Toggle - 开关

@State private var isOn = falseToggle("启用通知", isOn: $isOn).toggleStyle(.switch) // 开关样式.tint(.green)         // 自定义颜色

5.2、Picker - 选择器

enum Flavor: String, CaseIterable {case chocolate, vanilla, strawberry
}@State private var selectedFlavor = Flavor.chocolatePicker("选择口味", selection: $selectedFlavor) {ForEach(Flavor.allCases, id: \.self) { flavor inText(flavor.rawValue.capitalized)}
}
.pickerStyle(.menu) // 菜单样式

5.3、Slider - 滑块

@State private var volume: Double = 50Slider(value: $volume,in: 0...100,step: 5,label: { Text("音量") },minimumValueLabel: { Text("0") },maximumValueLabel: { Text("100") }
)

5.4、Stepper - 步进器

@State private var quantity = 1Stepper("数量: \(quantity)", value: $quantity, in: 1...10)

5.5、DatePicker - 日期选择

@State private var date = Date()DatePicker("选择日期", selection: $date, displayedComponents: .date).datePickerStyle(.graphical) // 日历样式

六、列表与集合视图

6.1、List - 列表视图

struct Item: Identifiable {let id = UUID()let name: String
}let items = [Item(name: "苹果"), Item(name: "香蕉"), Item(name: "橙子")]List(items) { item inText(item.name)
}
.listStyle(.insetGrouped) // 分组样式

6.2、ScrollView - 滚动视图

ScrollView {LazyVStack { // 懒加载VStackForEach(1...100, id: \.self) { index inText("项目 \(index)").padding().frame(maxWidth: .infinity).background(index % 2 == 0 ? .blue.opacity(0.1) : .green.opacity(0.1))}}
}

6.3、Grid - 网格布局 (iOS 16+)

let columns = [GridItem(.adaptive(minimum: 100))]ScrollView {LazyVGrid(columns: columns, spacing: 20) {ForEach(1...20, id: \.self) { index inColor.blue.frame(height: 100).overlay(Text("\(index)").foregroundStyle(.white).font(.title)).cornerRadius(10)}}.padding()
}

七、进度指示器

7.1、ProgressView - 进度条

// 不确定进度
ProgressView("加载中...")// 确定进度
@State private var progress = 0.5ProgressView(value: progress).progressViewStyle(.linear) // 线性样式// 环形进度
ProgressView(value: progress).progressViewStyle(.circular)

7.2、ActivityIndicator - 活动指示器 (UIKit桥接)

struct ActivityIndicator: UIViewRepresentable {func makeUIView(context: Context) -> UIActivityIndicatorView {let view = UIActivityIndicatorView(style: .large)view.startAnimating()return view}func updateUIView(_ uiView: UIActivityIndicatorView, context: Context) {}
}// 使用
ActivityIndicator()

八、容器视图

8.1、VStack/HStack/ZStack - 基础布局

ZStack { // 层叠布局Color.blue.opacity(0.2)VStack(spacing: 20) { // 垂直布局Text("标题").font(.title)HStack { // 水平布局Image(systemName: "star.fill")Text("5星评价")}}
}
.frame(height: 200)
.cornerRadius(15)

8.2、LazyVStack/LazyHStack - 懒加载布局

ScrollView {LazyVStack { // 只渲染可见部分ForEach(1...1000, id: \.self) { item inText("项目 \(item)").padding().onAppear { print("加载项目 \(item)") }}}
}

8.3、Group/GroupBox - 内容分组

Group {Text("第一行")Text("第二行")
}GroupBox(label: Label("设置", systemImage: "gear")) {Toggle("选项1", isOn: .constant(true))Toggle("选项2", isOn: .constant(false))
}

九、导航相关

9.1、NavigationStack - 导航栈

struct ContentView: View {var body: some View {NavigationStack {List {NavigationLink("个人资料", value: "profile")NavigationLink("设置", value: "settings")}.navigationDestination(for: String.self) { id inswitch id {case "profile": ProfileView()case "settings": SettingsView()default: EmptyView()}}.navigationTitle("首页")}}
}

9.2、TabView - 标签页

TabView {HomeView().tabItem {Label("首页", systemImage: "house")}ProfileView().tabItem {Label("我的", systemImage: "person")}
}
.tint(.purple) // 标签颜色

十、弹窗与提示

10.1、Alert - 警告框

@State private var showAlert = falseButton("显示警告") {showAlert = true
}
.alert("确认删除?", isPresented: $showAlert) {Button("删除", role: .destructive) {}Button("取消", role: .cancel) {}
} message: {Text("此操作不可恢复")
}

10.2、Sheet - 底部表单

@State private var showSheet = falseButton("显示表单") {showSheet = true
}
.sheet(isPresented: $showSheet) {VStack {Text("表单内容")Button("关闭") {showSheet = false}}.presentationDetents([.medium, .large]) // 高度控制 (iOS 16+)
}

10.3、Toast - 提示 (自定义实现)

struct ToastModifier: ViewModifier {@Binding var isShowing: Boollet message: Stringfunc body(content: Content) -> some View {ZStack {contentif isShowing {VStack {Spacer()Text(message).padding().background(Color.black.opacity(0.7)).foregroundStyle(.white).cornerRadius(8).transition(.opacity)}.padding().onAppear {DispatchQueue.main.asyncAfter(deadline: .now() + 2) {withAnimation {isShowing = false}}}}}}
}// 使用
Button("显示Toast") {showToast = true
}
.modifier(ToastModifier(isShowing: $showToast, message: "操作成功"))

十一、形状与绘图

11.1、基础形状

VStack(spacing: 20) {Circle().fill(.red).frame(width: 80, height: 80)Rectangle().fill(.blue.gradient).frame(width: 150, height: 80)Capsule().fill(.green).frame(width: 200, height: 60)
}

11.2、自定义形状

struct Triangle: Shape {func path(in rect: CGRect) -> Path {var path = Path()path.move(to: CGPoint(x: rect.midX, y: rect.minY))path.addLine(to: CGPoint(x: rect.minX, y: rect.maxY))path.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))path.closeSubpath()return path}
}// 使用
Triangle().fill(.orange).frame(width: 100, height: 100)

十二、高级控件

12.1、Canvas - 绘图画布 (iOS 15+)

Canvas { context, size in// 绘制矩形let rect = CGRect(x: 50, y: 50, width: 200, height: 100)context.fill(Path(rect), with: .color(.blue))// 绘制文本let text = "SwiftUI绘图"context.draw(Text(text).font(.title), at: CGPoint(x: size.width/2, y: 200))
}
.frame(height: 300)

12.2、Charts - 图表框架 (iOS 16+)

import Chartsstruct SalesData {let month: Stringlet revenue: Double
}let data = [SalesData(month: "1月", revenue: 5000),SalesData(month: "2月", revenue: 8000),SalesData(month: "3月", revenue: 6500)
]Chart(data) {BarMark(x: .value("月份", $0.month),y: .value("收入", $0.revenue)).foregroundStyle(by: .value("月份", $0.month))
}
.frame(height: 200)
.padding()

最佳实践建议

1、组合使用:通过组合简单控件创建复杂UI

func InfoCard(title: String, value: String) -> some View {VStack(alignment: .leading) {Text(title).font(.caption).foregroundStyle(.secondary)Text(value).font(.title2)}.padding().background(RoundedRectangle(cornerRadius: 10).fill(Color(.systemBackground))).shadow(radius: 2)
}

2、响应式设计:使用 @ViewBuilder 和条件语句

@ViewBuilder
var loadingView: some View {if isLoading {ProgressView()} else {ContentView()}
}

3、平台适配

.padding()
#if os(iOS)
.background(Color(.systemGray6))
#endif

4、性能优化

  • 对列表使用 Lazy 视图
  • 避免在视图主体中执行繁重操作
  • 使用 EquatableView 减少不必要的刷新

SwiftUI 的控件设计遵循声明式理念,通过组合和修饰符可以创建出高度定制化的界面。掌握这些基础控件的使用是构建复杂应用的基础。

http://www.dtcms.com/a/279438.html

相关文章:

  • SCI特刊征稿
  • 延迟双删懂不
  • .net swagger的API项目里面 同时可以运行wwwroot里面的网页
  • Java 中的异步编程详解
  • Desktop Extensions (DXT) 详解
  • CA翻译~
  • 12.如何判断字符串是否为空?
  • 153、寻找旋转排序数组中的最小值
  • 本地线程(Native Thread)、主线程(UI 线程) 和 子线程(Java 子线程)
  • Axure RP Extension for Chrome插件安装使用
  • 在 Ubuntu 上安装 vLLM:从 GPU 到 CPU 的三种方案
  • Oracle根据一张表的字段更新另一张表中的数据
  • Android 自定义路由系统
  • ServiceLibrary 库使用演示
  • [AI8051U入门第一步]环境安装和按键控制流水灯
  • 将dist文件打包成exe可执行程序
  • MySQL服务故障分析报告​​
  • 以楼宇自控系统为抓手,实现人居环境优化与建筑能效跃升
  • 职业教育领域的“101计划
  • keepalive模拟操作部署
  • 学习日志09 python
  • 【SVN】SVN 客户端的安装与操作
  • 设计模式之代理模式:掌控对象访问的优雅之道
  • CVE-2017-7525源码分析与漏洞复现(Jackson 反序列化)
  • Android 中 实现格式化字符串
  • vue2/3生命周期使用建议
  • TCL在芯片设计与验证中的应用实践
  • WinUI3开发_Combobox实现未展开时是图标下拉菜单带图标+文字
  • ConcurrentHashMap 原子操作详解:computeIfAbsent、computeIfPresent和putIfAbsent
  • 技术人生——第12集:思想为王,功能在后