SwiftUI vs UIKit 2026:选哪个、怎么混用不踩坑
SwiftUI 已经发布 7 年。"应该用 SwiftUI 吗"这个问题不再是"框架准备好了没"——准备好了。而是"你在做什么类型的 app"。这是真用两种方案各发版过几年之后的诚实看法。
SwiftUI 在 2026 的状态
2019 年坎坷上线后的重大进步:
- 性能 — iOS 17+ 上 SwiftUI 真的快了,新渲染器 + @Observable 替代 ObservableObject。
- 导航 —
NavigationStack终于提供了不和框架打架的程序化导航。 - 列表虚拟化 —
LazyVStack/List现在真正虚拟化。 - 自定义布局 —
Layout协议解锁了过去必须 UIKit 才能做的事。
仍然粗糙的地方:
- 复杂 collection view(重排、多分区粘性头)UIKit 仍然更顺手。
- 地图/视频/摄像头集成多半还要
UIViewRepresentable。 - 超出
matchedGeometryEffect的自定义转场仍受限。
什么时候用 SwiftUI 起新页面
- 表单、列表、设置页、详情页 → SwiftUI。
- 数据驱动的动态布局 → SwiftUI(@Observable + body 模型很合适)。
- 要同时跑 iPad、Mac Catalyst、visionOS → SwiftUI。
什么时候伸手去拿 UIKit
- 重度
UICollectionViewCompositionalLayout+ 自定义补充视图。 - 深度 AVFoundation 集成 + 自定义预览 UI。
- 老 app 里有数千行
UIViewController,扩展比重写省事。 - 需要 SwiftUI 还没暴露的精准手势/触摸处理。
怎么把两者混好
边界是 UIHostingController(UIKit 装 SwiftUI)和 UIViewControllerRepresentable(SwiftUI 装 UIKit)。两条规则:
1. 在 controller 层级跨边界,不在 view 层级
// 好 —— 包整个屏幕 let host = UIHostingController(rootView: SettingsView()) navigationController.pushViewController(host, animated: true) // 危险 —— 把一小段 SwiftUI 嵌进 UIKit cell // 会引发生命周期与尺寸问题,避免。
2. 不要直接共享可变状态跨边界
传不可变快照进去,事件通过回调或 Combine 发出来。把 @ObservableObject 实例同时塞两边理论可行,实操会出引用 bug。
struct SettingsView: View { let initialPrefs: Prefs let onSave: (Prefs) -> Void }
导航 — 最棘手的话题
2026 年的答案:
- 新 app →
NavigationStack+Path用[any Hashable]或自定义 enum。 - 已有 UIKit app → 保留
UINavigationController,叶子页面用UIHostingController包。 - 混合 → 用 UIKit 导航做底盘,SwiftUI 页面是乘客。
会让人翻车的模式:让 SwiftUI NavigationStack 和 UINavigationController 平级并存。选一个做底盘。
性能现实检查
90% 的页面 SwiftUI 已经够快,你测不出差别。剩下 10%:
- 长滚动列表 + 复杂 cell → 先测。SwiftUI 的
List已有竞争力,真测到掉帧再回到UICollectionView。 - 实时绘制(图表、自定义画布)→
Canvas够好,但最难的场景CADisplayLink+ Metal 仍胜。 - 动画密集的引导流 → SwiftUI 实际更好;声明式动画模型很强。
实际选型
- 新 C 端 iOS app → SwiftUI 上下通吃。第三方组件强制时才
UIViewRepresentable。 - iPad / Mac / visionOS → 必须 SwiftUI。
- 内嵌进别人 app 的 SDK → UIKit,因为你不知道宿主 app 的 iOS 部署版本。
- 银行 8 年 UIKit 老 app → 不重写。新页面用 SwiftUI + hosting controller 即可。
反模式
- "为学 SwiftUI" 重写跑得好的 UIKit app。 业余项目学,别赌一个季度。
- 5 屏 SwiftUI app 上自定义 Coordinator 模式。 用
NavigationStack,Coordinator 是 UIKit 时代的补丁。 - 强行让 SwiftUI 兼容 iOS 14。 能跑,但 API 缺口太大。如果能放弃 iOS 14 就放弃。
- "团队会 ObservableObject" 就不用 @Observable。 macro 显著更清爽,迁移机械化。
一句话总结
- 2026 新代码默认 SwiftUI。
- UIKit 仍适合:老代码维护、深度 AVFoundation、特定 UICollectionView 场景。
- 在 controller 边界混,不在 view 边界混。
- 导航选一个底盘。
- 不要"为干净"重写跑得好的 UIKit 代码——那从来不是真正的 ROI。
相关阅读
TypeScript 类型体操:什么时候值,什么时候在炫技
务实的 TypeScript 高级类型指南 — mapped types、conditional types、template literal types 真正能给你什么,什么时候用,什么时候应该退回到朴素代码。
Kubernetes 资源 requests / limits 实战:不会把生产搞挂的设法
怎么在生产里实际设 Kubernetes CPU 与内存的 requests/limits — QoS 类、CPU 节流、OOM kill、那些害公司钱的差别,以及好使的模式。
Vue 3 vs React 2026:下个项目的诚实对比
2026 年 Vue 3 与 React 的诚实对比 — Composition API vs Hooks、性能、生态、TypeScript 表现,以及真正决定选型的标准。