一、属性包装器(Property Wrappers)
用于管理数据流、状态和与视图的交互。
1. @State
2. @Binding
3. @ObservedObject
4. @StateObject
5. @EnvironmentObject
6. @Environment
7. @FetchRequest
(Core Data)
- 作用:自动从 Core Data 中获取数据。
- 示例:
struct TaskListView: View {
@FetchRequest(
entity: Task.entity(),
sortDescriptors: [NSSortDescriptor(keyPath: \Task.date, ascending: true)]
) var tasks: FetchedResults<Task>
var body: some View {
List(tasks) { task in
Text(task.title ?? "")
}
}
}
8. @AppStorage
/ @SceneStorage
二、关键视图修饰符(View Modifiers)
用于调整视图的布局、样式或行为。
1. 布局修饰符
2. 样式修饰符
3. 交互修饰符
4. 动画修饰符
四、属性包装器(Property Wrappers)总结
1. 数据管理
属性包装器 | 作用 | 示例代码 |
---|
@State | 管理视图内部私有状态,值变化触发视图更新。 | @State private var isEnabled = true |
@Binding | 建立父子视图间的双向数据绑定。 | @Binding var text: String → 父视图传递 $text |
@StateObject | 持有符合 ObservableObject 的对象,生命周期与视图一致。 | @StateObject var viewModel = UserViewModel() |
@ObservedObject | 观察外部 ObservableObject 对象,不持有所有权。 | @ObservedObject var dataModel: DataModel |
@EnvironmentObject | 从环境全局共享对象,避免逐层传递。 | @EnvironmentObject var settings: AppSettings |
@Environment | 读取系统或自定义环境值(如设备特征)。 | @Environment(.horizontalSizeClass) var sizeClass |
@AppStorage | 轻量级持久化存储,基于 UserDefaults 。 | @AppStorage("username") var name: String = "Anonymous" |
@SceneStorage | 场景级存储,用于多窗口应用的状态恢复。 | @SceneStorage("selectedTab") var tab: Int = 0 |
@FocusedValue | 监听当前焦点所在视图的值(如 TextField 聚焦时)。 | @FocusedValue(.username) var currentUsername |
@GestureState | 跟踪手势交互的临时状态(如拖拽偏移量)。 | @GestureState var dragOffset = CGSize.zero |
2. 数据流与模型
属性包装器 | 作用 | 示例代码 |
---|
@Published | 标记 ObservableObject 中需要发布变化的属性。 | class User: ObservableObject { @Published var name = "John" } |
@FetchRequest | 自动从 Core Data 中获取数据(需导入 CoreData )。 | @FetchRequest(sortDescriptors: []) var items: FetchedResults<Item> |
@Query (SwiftData) | SwiftData 中的数据查询(iOS 17+)。 | @Query var users: [User] |
3. UI 交互
属性包装器 | 作用 | 示例代码 |
---|
@FocusState | 控制 TextField 等组件的焦点状态。 | @FocusState private var isEmailFocused: Bool |
@Namespace | 创建动画命名空间,用于匹配视图间的动画过渡。 | @Namespace private var animationNamespace |
五、视图修饰符(View Modifiers)
1. 布局与尺寸
修饰符 | 作用 | 示例代码 |
---|
.frame(width:height:) | 设置视图尺寸,可指定对齐方式。 | .frame(width: 200, height: 100, alignment: .center) |
.padding(_:) | 添加内边距。 | .padding(.horizontal, 20) |
.offset(x:y:) | 偏移视图位置。 | .offset(x: 10, y: -5) |
.position(x:y:) | 绝对定位视图中心点(相对于父视图坐标)。 | .position(x: 100, y: 200) |
.aspectRatio(_:contentMode:) | 控制视图宽高比。 | .aspectRatio(16/9, contentMode: .fit) |
2. 样式与外观
修饰符 | 作用 | 示例代码 |
---|
.foregroundColor(_:) | 设置前景色(文本、图标颜色)。 | .foregroundColor(.blue) |
.background(_:alignment:) | 设置背景视图或颜色。 | .background(Color.yellow.opacity(0.3)) |
.cornerRadius(_:) | 添加圆角(iOS 15+ 推荐使用 .clipShape 更灵活)。 | .cornerRadius(10) |
.shadow(color:radius:x:y:) | 添加阴影。 | .shadow(color: .gray, radius: 5, x: 2, y: 2) |
.blur(radius:opaque:) | 添加模糊效果。 | .blur(radius: 3) |
.opacity(_:) | 设置透明度(0~1)。 | .opacity(0.5) |
3. 文本与字体
修饰符 | 作用 | 示例代码 |
---|
.font(_:) | 设置字体样式。 | .font(.system(size: 16, weight: .bold, design: .rounded)) |
.lineLimit(_:) | 限制文本行数。 | .lineLimit(3) |
.multilineTextAlignment(_:) | 多行文本对齐方式。 | .multilineTextAlignment(.trailing) |
.textFieldStyle(_:) | 设置 TextField 样式(如 .roundedBorder )。 | .textFieldStyle(.roundedBorder) |
4. 交互与事件
修饰符 | 作用 | 示例代码 |
---|
.onTapGesture(count:perform:) | 添加点击手势。 | .onTapGesture(count: 2) { print("双击") } |
.onLongPressGesture(minimumDuration:perform:) | 长按手势。 | .onLongPressGesture(minimumDuration: 1) { print("长按") } |
.gesture(_:) | 添加自定义手势(如拖拽、旋转)。 | .gesture(DragGesture().onChanged { value in ... }) |
.onSubmit(of:_:) | 响应键盘提交事件(如 TextField 回车)。 | .onSubmit { print("提交") } |
.disabled(_:) | 禁用视图交互。 | .disabled(!isFormValid) |
5. 动画与过渡
修饰符 | 作用 | 示例代码 |
---|
.animation(_:value:) | 为特定值变化添加动画。 | .animation(.spring(), value: isExpanded) |
.transition(_:) | 定义视图插入或移除的过渡效果。 | .transition(.asymmetric(insertion: .scale, removal: .opacity)) |
.matchedGeometryEffect(id:in:) | 关联两个视图的几何属性,用于平滑动画。 | .matchedGeometryEffect(id: "circle", in: animationNamespace) |
6. 列表与滚动视图
修饰符 | 作用 | 示例代码 |
---|
.listRowSeparator(_:) | 设置列表行分隔线样式(iOS 15+)。 | .listRowSeparator(.hidden) |
.scrollIndicators(_:) | 控制滚动条显示(iOS 16.4+)。 | .scrollIndicators(.never) |
.scrollTargetBehavior(_:) | 指定滚动行为(如分页滚动,iOS 17+)。 | .scrollTargetBehavior(.paging) |
7. 导航与弹窗
修饰符 | 作用 | 示例代码 |
---|
.navigationTitle(_:) | 设置导航栏标题。 | .navigationTitle("主页") |
.toolbar(_:) | 自定义导航栏工具按钮。 | .toolbar { ToolbarItem(placement: .primaryAction) { Button("完成") {} } } |
.alert(_:isPresented:actions:) | 显示弹窗。 | .alert("提示", isPresented: $showAlert) { Button("确定") {} } |
.sheet(isPresented:content:) | 显示模态视图。 | .sheet(isPresented: $showSheet) { SettingsView() } |
8. 高级功能
修饰符 | 作用 | 示例代码 |
---|
.task(priority:_:) | 在视图出现时启动异步任务,视图消失时自动取消(iOS 15+)。 | .task { await loadData() } |
.onChange(of:perform:) | 监听特定值的变化。 | .onChange(of: selectedTab) { print("Tab 切换为 (selectedTab)") } |
.preference(key:value:) | 传递视图层级中的偏好值(如子视图尺寸)。 | .preference(key: SizePreference.self, value: geometry.size) |
六、组合与最佳实践
1. 属性包装器组合示例
struct ContentView: View {
@StateObject private var userModel = UserModel()
@Environment(.colorScheme) var colorScheme
@FocusState private var isInputFocused: Bool
var body: some View {
VStack {
TextField("输入用户名", text: $userModel.name)
.focused($isInputFocused)
.padding()
.background(colorScheme == .dark ? Color.gray : Color.white)
.cornerRadius(8)
Button("提交") {
isInputFocused = false
}
.disabled(userModel.name.isEmpty)
}
.animation(.easeInOut, value: isInputFocused)
}
}
2. 修饰符顺序的重要性
SwiftUI 的修饰符顺序会影响最终效果。例如:
Text("Hello")
.padding()
.background(.red)
七、总结
-
属性包装器:用于数据流管理(@State
, @Binding
)、状态共享(@EnvironmentObject
)、UI 交互(@FocusState
)。
-
视图修饰符:调整布局(.frame
, .padding
)、样式(.foregroundColor
, .font
)、交互(.onTapGesture
, .disabled
)。
-
组合使用:通过合理组合修饰器和包装器,可以构建灵活、高效的 SwiftUI 界面。
-
根据场景选择合适的工具:简单状态用 @State
,跨视图共享用 @EnvironmentObject
,持久化用 @AppStorage
。