swiftui-patterns
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseSwiftUI Patterns (iOS 17+)
SwiftUI Patterns (iOS 17+)
SwiftUI 17+ removes ObservableObject boilerplate with @Observable, simplifies environment injection with @Environment, and introduces task-based async patterns. The core principle: use Apple's modern APIs instead of reactive libraries.
SwiftUI 17+ 借助@Observable移除了ObservableObject的冗余代码,通过@Environment简化了环境注入,并引入了基于任务的异步模式。核心原则:使用Apple的现代API而非响应式库。
Overview
概述
Quick Reference
快速参考
| Need | Use (iOS 17+) | NOT |
|---|---|---|
| Observable model | | |
| Published property | Regular property | |
| Own state | | |
| Passed model (binding) | | |
| Environment injection | | |
| Environment access | | |
| Async on appear | | |
| Value change | | |
| 需求 | iOS 17+ 推荐用法 | 不推荐用法 |
|---|---|---|
| 可观察模型 | | |
| 可发布属性 | 常规属性 | |
| 自有状态 | | |
| 传递的模型(绑定) | | |
| 环境注入 | | |
| 环境访问 | | |
| 出现时执行异步操作 | | |
| 值变更 | | |
Core Workflow
核心工作流程
- Use for model classes (no @Published needed)
@Observable - Use for view-owned models,
@Statefor passed models@Bindable - Use for async work (auto-cancels on disappear)
.task { } - Use with
NavigationStackfor programmatic navigationNavigationPath - Apply and
.accessibilityLabel()to interactive elements.accessibilityHint()
- 为模型类使用(无需@Published)
@Observable - 视图自有模型使用,传递的模型使用
@State@Bindable - 异步工作使用(在视图消失时自动取消)
.task { } - 结合与
NavigationStack实现程序化导航NavigationPath - 为交互元素添加和
.accessibilityLabel().accessibilityHint()
Reference Loading Guide
参考资料加载指南
ALWAYS load reference files if there is even a small chance the content may be required. It's better to have the context than to miss a pattern or make a mistake.
| Reference | Load When |
|---|---|
| Observable | Creating new |
| State Management | Deciding between |
| Environment | Injecting dependencies into view hierarchy |
| View Modifiers | Using |
| Migration Guide | Updating iOS 16 code to iOS 17+ |
| MVVM Observable | Setting up view model architecture |
| Navigation | Programmatic or deep-link navigation |
| Performance | Lists with 100+ items or excessive re-renders |
| UIKit Interop | Wrapping UIKit components (WKWebView, PHPicker) |
| Accessibility | VoiceOver, Dynamic Type, accessibility actions |
| Async Patterns | Loading states, refresh, background tasks |
| Composition | Reusable view modifiers or complex conditional UI |
只要有哪怕一点点可能需要用到相关内容,就务必加载参考文件。拥有上下文总比遗漏模式或犯错要好。
| 参考资料 | 加载场景 |
|---|---|
| Observable | 创建新的 |
| State Management | 决定使用 |
| Environment | 向视图层级注入依赖时 |
| View Modifiers | 使用 |
| Migration Guide | 将iOS 16代码升级到iOS 17+时 |
| MVVM Observable | 搭建视图模型架构时 |
| Navigation | 实现程序化或深度链接导航时 |
| Performance | 处理包含100+条目的列表或过度重渲染问题时 |
| UIKit Interop | 封装UIKit组件(WKWebView、PHPicker)时 |
| Accessibility | 处理VoiceOver、动态类型、无障碍操作时 |
| Async Patterns | 实现加载状态、刷新、后台任务时 |
| Composition | 实现可复用视图修饰符或复杂条件UI时 |
Common Mistakes
常见错误
-
Over-usingfor passed models — Creating
@Bindablefor every property causes unnecessary view reloads. Use@Bindableonly for mutable model properties that need two-way binding. Read-only computed properties should use regular properties.@Bindable -
State placement errors — Putting model state in the view instead of a dedicatedmodel causes view logic to become tangled. Always separate model and view concerns.
@Observable -
NavigationPath state corruption — Mutatingincorrectly can leave it in inconsistent state. Use
NavigationPathwith proper state management to avoid path corruption.navigationDestination(for:destination:) -
Missingcancellation —
.taskhandles cancellation on disappear automatically, but nested Tasks don't. Complex async flows need explicit cancellation tracking to avoid zombie tasks..task -
Ignoring environment invalidation — Changing environment values at parent doesn't invalidate child views automatically. Useconsistently and understand when re-renders happen based on observation.
@Environment -
UIKit interop memory leaks —and
UIViewRepresentablecan leak if delegate cycles aren't broken. Weak references and explicit cleanup are required.UIViewControllerRepresentable
-
过度为传递的模型使用—— 为每个属性创建
@Bindable会导致不必要的视图重载。仅对需要双向绑定的可变模型属性使用@Bindable。只读计算属性应使用常规属性。@Bindable -
状态放置错误 —— 将模型状态放在视图中而非专用的模型中会导致视图逻辑混乱。务必分离模型和视图关注点。
@Observable -
NavigationPath状态损坏 —— 不正确地修改会使其处于不一致状态。使用
NavigationPath并配合正确的状态管理,以避免路径损坏。navigationDestination(for:destination:) -
遗漏取消处理 ——
.task会在视图消失时自动处理取消,但嵌套的Task不会。复杂的异步流程需要显式的取消跟踪,以避免僵尸任务。.task -
忽略环境失效 —— 在父视图中更改环境值不会自动使子视图失效。持续使用,并理解基于观察的重渲染触发时机。
@Environment -
UIKit互操作内存泄漏 —— 如果不打破委托循环,和
UIViewRepresentable可能会发生内存泄漏。需要使用弱引用和显式清理。UIViewControllerRepresentable