![]()
7 年前,苹果在 2019 年 WWDC 的压轴环节,正式向外界公布了。
这是一个姗姗来迟的产品——相比 Google 的 Flutter,SwiftUI 足足晚了两年亮相。但苹果依然选择将它放在当年 WWDC 的最后重磅发布,足以看出这套新框架在苹果内部的重要地位。
对于开发者而言,SwiftUI 为 iOS、macOS、watchOS、tvOS 等设备提供了一套统一的 UI 框架,它曾经承载着一个非常美好的愿景:未来,开发 Apple 生态应用将不再需要面对不同平台间割裂的开发体验。当时,无数人翘首以盼,期待这会成为苹果下一代应用开发的基石。
但 7 年过去,曾经的期待,如今还剩下多少?
来自一位开发者 Yakov Manshin 的评价或许代表了不少开发者的真实感受:“到了 2026 年,SwiftUI 依然给许多开发者一种‘长期测试版’的感觉。”
这句话迅速引发了开发者社区的共鸣。
在他发表的《SwiftUI After 7 Years: A Story of Mediocrity》一文中,Yakov Manshin 回顾了 SwiftUI 七年来的发展历程,并试图回答一个问题:为什么一个曾经让开发者充满期待的框架,最终却逐渐成为许多资深工程师眼中的失望之作?
接下来,他将拆解苹果的 SwiftUI 在性能、布局可预测性等方面长期存在的问题,梳理其数据流设计不断变化带来的混乱,以及令人头疼的向后兼容问题——这些问题迫使开发者不得不依赖大量适配层和临时方案,才能让项目继续稳定运行。
通过真实案例,包括苹果官方 SwiftUI 教程自身暴露的问题,以及 SwiftUI 与 UIKit 的性能正面对比,下文也试图展示:SwiftUI 看似带来了更简单、更现代的开发体验,但这种简化背后,也意味着开发者逐渐失去了对应用行为的精准控制。
而这篇文章讨论的,其实并不只是一个 UI 框架的问题。在更深层次上,它也折射出苹果软件开发文化的变化——从早期 Cocoa、Aqua 和 Auto Layout 时代对产品工艺、细节打磨近乎苛刻的追求,到如今更加倾向于“够用就行”的现代企业文化。
如果你已经厌倦了不断为 SwiftUI 的缺陷寻找解释,反复与布局 Bug 斗争,或者一次次替苹果完成本该由他们承担的质量验证工作,那么这篇文章或许值得一读。
来源:https://ykvm.com/2026/07/swiftui-a-story-of-mediocrity/
作者 | Yakov Manshin 责编 | 苏宓
出品 | CSDN(ID:CSDNnews)
SwiftUI 于 2019 年正式发布,并引发了巨大的关注。我当时就在现场,也亲眼见证了这一切。苹果当时承诺,它将终结开发者与 Auto Layout 长期斗争的时代,也不必因为一次微小的改动就反复重构整个应用。
![]()
取而代之的,是声明式语法、单一数据源、内置动画、即时预览,以及代码在苹果全平台之间的复用能力。对我来说,这听起来好得令人难以置信。
事实证明,确实如此。
到了现在,最初的兴奋感不仅已经消退,甚至逐渐转变成一种越来越强烈的职业挫败感。
而七年之后,“SwiftUI 仍然只是一个年轻框架”这种说法,已经站不住脚了。在这个行业里,七年几乎等同于一个漫长时代。它大致相当于从这个版本到那个版本之间的时间跨度,也超过了第一代 iPhone 发布到 iOS 7 重新设计之间的时间。
相比之下,SwiftUI 给人的感觉更像是一直处于测试阶段。每一个新功能背后,都伴随着一堆隐藏在细则里的限制条件。每一次布局修复,都可能导致两个你根本没有修改过的地方出现新的问题。
说实话,我已经厌倦了在自己的项目里不断为这些问题寻找借口。
![]()
为什么 SwiftUI 会出现
不过,在我们深入了解 SwiftUI 的具体优势和缺陷之前,我们先来看看 SwiftUI 为什么会出现。
这并不完全是因为苹果想要为开发者提供更好的开发工具,而是因为它某种程度上不得不这么做。苹果需要回应来自竞争对手的压力。
到了 2010 年代中期,Facebook 的 React 已经成为 Web 开发领域事实上的标准,随后 React Native 和谷歌的 Flutter 也开始向移动平台发起进攻。这两个框架都采用了响应式和声明式的设计理念。
从任何一家企业的角度来看,继续开发原生应用开始显得越来越不划算。相比之下,他们可以使用同一套代码库同时支持 iOS 和 Android,并且还能复用自己网站上的组件。
我认为还有另一个原因,那就是 Mac App Store。
你可以回忆一下,上一次打开它是什么时候?你上一次在 Mac 上安装一个新的原生应用又是什么时候?没错,我也是一样。
iOS App Store 是苹果向服务业务转型过程中的关键一步,原因在于它可以从每一笔交易中抽取 30% 的分成。但在 Mac 平台上,许多应用要么只能通过浏览器使用,要么只是基于 Electron 封装的 Web 应用。
SwiftUI 原本被寄予厚望,希望同时解决这两个问题:一方面,让开发者继续留在原生生态中构建新的应用;另一方面,让已有应用更容易迁移到 Mac 平台。
响应式数据流、声明式布局,以及跨平台支持,是 SwiftUI 最核心的卖点。
那么,苹果是否兑现了这些承诺?让我们继续深入看看。
![]()
数据流
一直困扰着资深工程师(包括我自己)的一大痛点,就是数据流问题。理论上,“单一数据源”听起来像是一个完美的设计理念。但在实际使用中,它却变成了一团由属性包装器、宏以及不断变化的配套框架组成的混乱系统。
最开始,我们使用的是 @State、@Binding 和 ObservedObject。随后苹果意识到这种方式的性能表现非常糟糕,SwiftUI 会不断重新渲染视图。
于是,它推出了 Observation 框架以及 @Observable 宏。苹果试图通过编译器层面的技巧来解决这个问题,但显然这还远远不够,因此布局引擎依旧像是在不断猜测。
在 SwiftUI 中,你永远无法确定一个视图到底会更新多少次,以及它为什么会选择在某个时刻进行更新。即使使用那些没有公开文档的调试 API,也无法获得完整的信息。
SwiftUI 的数据流确实是响应式的——但有时候,我甚至希望它不要这么响应,因为它经常以错误的方式做出反应。它会响应那些本应该忽略的变化,却忽略那些真正重要的变化。
在我看来,SwiftUI 的响应机制就像一个黑盒:它让实现可预测的行为变得几乎不可能。
![]()
布局系统
这也引出了 SwiftUI 在架构层面的问题。接下来,我们聊聊 SwiftUI 的布局系统。
如果你曾经构建过任何复杂一点的界面,那么你一定知道 SwiftUI 带来的挫败感。它的布局引擎极其不可预测。
SwiftUI 建立在“尺寸协商”的理念之上。在发布会演示中,这听起来非常合理,但当你真正尝试构建一个浮动视图或者自定义侧边栏时,它就会变成一场噩梦。
说到自定义侧边栏,苹果 SwiftUI 教程里的那个示例项目(https://developer.apple.com/tutorials/swiftui/creating-a-macos-app)使用的是一个非常标准、没有任何定制的侧边栏。你用最新版 Xcode 构建项目,再用最新版 macOS 启动应用——结果却会看到这样的情况。
![]()
我第一次注意到这个问题是在两年多以前,而从那以后,一切都没有改变。
哦,抱歉,有一件事变了。
由于 Liquid Glass 的加入,现在按钮的尺寸也发生了变化——当然,这个问题严格来说并不能算是 SwiftUI 的问题。
但真正属于 SwiftUI 的问题,是整个 UI 布局系统的脆弱性。它们会以最意想不到的方式、在最不合适的时刻崩溃。
你可以在真正投入生产的应用中看到这种情况,比如 UTM。它是一款非常出色的工程作品,但由于大量依赖 SwiftUI,有时候它给人的感觉更像是一个早期原型。
最终,你会发现自己不得不用 GeometryReader 包裹所有东西。而这其实就是一种彻底失败的表现。一旦使用了 GeometryReader,你就已经失去了 SwiftUI 最核心的声明式优势。现在,你必须手动计算坐标,而且代码量甚至比 Auto Layout 还要复杂——这本身就非常讽刺。
更糟糕的是,仅仅因为 SwiftUI 的布局系统又发生了一次变化,你可能下一次更新时就不得不重新编写所有坐标计算逻辑。
![]()
API 稳定性与功能完整性
接下来,我们聊聊 API 稳定性以及功能完整性——或者说,SwiftUI 在这方面的欠缺。
如果你查看任何一个现代 SwiftUI 项目的代码库,你都会发现里面充斥着大量 if 判断,多到几乎令人觉得滑稽——实际上却令人尴尬。
2019 年的时候,有人还在畅谈“写更少的代码,写更好的代码”。那么七年过去之后,我们得到的是什么?
比如说,你希望像从 iOS 7 时代开始那样,在用户滚动页面时隐藏键盘。抱歉,在 SwiftUI 中实现这个功能,你需要 iOS 16。
也许你也想让用户自定义窗口工具栏,就像他们从 2001 年(大概是那个时候)开始就可以做到的事情一样。而 SwiftUI 直到几年前才终于获得了这个所谓的“突破性”功能。
然后还有一个最基础的任务:显示你从网络获取的图片。
不过,你最好自己写一个图片加载器,因为 AsyncImage 直到 iOS 15 才被引入。
但如果你还希望对这些图片进行缓存,我有一个坏消息告诉你:你根本做不到。因为直到现在(2026 年 7 月)这个 API 依然处于测试阶段。
对于这些场景,开发者通常只能自己创造各种变通方案和临时解决办法。而当苹果最终提供那些早在 AppKit 或 UIKit 中存在了几十年的 API 时,你却不得不同时维护多套实现。
但即使你使用的 API 是 SwiftUI 第一版就已经提供的,也很有可能它后来被重新命名,或者被一个功能相近的新 API 替代。
一个典型例子就是 NavigationView。它一直以来都以 Bug 众多而闻名。看起来,苹果并没有选择修复它,而是决定直接用 NavigationStack 替换整个组件。但这又意味着,你必须同时维护两套代码分支:一套支持新系统,一套兼容旧版本。
所以,这到底算是“更少的代码”,还是“更好的代码”?你来告诉我吧,因为我自己也有点搞不清楚。
这种持续不断的 API 更替,最终导致了开发地狱。我们本应该只需要声明一次 UI 结构,但实际上,我们不得不为兼容性编写各种适配层和补丁,然后祈祷它们不会在下一次系统更新中崩溃。某种意义上,我们实际上是在替苹果完成它应该做的质量测试工作。
这些问题本应该在 2019 年解决——好吧,至少应该在 2020 年解决。然而,七年过去了,SwiftUI 依然没有实现与那些所谓“遗留”框架相同的功能完整性。SwiftUI 就像是在原地打转,而我们只能跟着它一起跑,才能勉强停留在原来的位置。
但你知道吗?如果苹果没有假装 SwiftUI 已经足够稳定,并且可以作为未来几十年的基础,这些问题其实都不会成为如此严重的问题。如果你可以直接调用最新 API 编写代码,然后将它回溯部署到旧版本 iOS 上,这些问题也不会存在。是的,你仍然需要更频繁地重构代码,逐步淘汰旧实现。但至少,当前版本的代码可以在所有设备上保持一致运行。
这也是 Android 现代 UI 框架采用的方式。Jetpack Compose 本质上只是一个通过依赖管理器获取和更新的软件包。之后,它会直接被打包进你的应用程序中,并且可以运行在最早 2014 年左右的设备上——同时还能提供完全一致的 UI 表现。
![]()
性能
接下来,我们聊聊性能。
这是一个无法掩盖的问题——即使苹果仍然试图通过只展示 SwiftUI 在最新硬件上的运行效果来淡化它。但事实是,无论苹果多少次承诺会改进,SwiftUI 的性能依然没有达到应有的标准。它并不像一个运行在“高端平台”上的“第一方核心框架”应该有的表现。
比如,这是我自己做的 UIKit 与 SwiftUI 的正面对比测试。测试内容非常简单:一个图片画廊,来自我之前版本的 Playground 应用。
![]()
为什么是之前版本?因为后来我已经使用终极跨平台框架重新构建了整个应用。不过,那是另一个故事了。
回到测试本身。即使采用了各种性能优化手段,比如在后台线程解码图片,SwiftUI 网格视图的滚动体验依然明显不够流畅。更不用说,如果你必须记住一些晦涩难懂的优化技巧,才能让它正常运行,那么 SwiftUI 最初承诺的简单性就已经荡然无存了。
这只是我进行的多个测试中的一个,而且我特意选择了一台较旧的 iPhone。但其实这不应该成为借口。因为如果你需要一颗 M5 Pro Max 级别的超级芯片,才能流畅展示一堆 JPEG 图片,那说明你的整个架构存在严重问题。
高质量软件不应该这样构建,它本来就不应该以这种方式工作。
![]()
跨平台神话
这就引出了 SwiftUI 最后的一个承诺——跨平台支持。
我看过几场早期的 SwiftUI 发布会。公平地说,我并没有在其中任何一场听到“一次编写,随处运行”(write once, run anywhere)这样的说法。苹果通常使用的表述是:“学习这些工具一次,然后将它们应用到所有平台。”
但这里存在一个问题。你在 iOS 上学到的 SwiftUI 知识,很少能够直接应用到 Mac 上的布局开发中。除非你最终想做出那种看起来格格不入的 UI——就像苹果把 iPad 应用带到 Mac 上之后的那些应用一样。
SwiftUI 的核心概念,比如数据流和组合式布局,在不同平台之间大致是一致的。但你实际使用的具体组件,以及配置这些组件的方式,往往完全不同。更不用说,同一个视图组件在不同平台上的实现方式,也可能存在差异。
换句话说,为一个 6 英寸手机设计 UI,和为一台 27 英寸桌面电脑设计 UI,本来就不是一回事。谁能想到呢?
根据我的经验,SwiftUI 所谓的“学一次,到处应用”,经常会变成:“学一次,学两遍,到处应用,处处调试。”
当然,前提是你希望构建出真正符合平台习惯、看起来专业的 UI。如果你不在意这一点,那么 SwiftUI 确实可以给你带来一些“能用”的结果,或者“差不多”的结果。
![]()
![]()
理念上的转变
事实上,我认为,这种“差不多就行”的心态才是这里最大的问题。我认为,它代表了苹果整个软件开发理念的一次重大转变。
随着 SwiftUI 的出现,我们进入了一个这样的时代:一个“大部分情况下能工作”的东西,就被认为已经足够。或者说,一个只覆盖 90% 使用场景的产品,也可以被认为是成功的。过去对于生产级质量和稳定性的要求,正在让位于所谓的“速度”。而“速度”这个词,通常是在你想要更快地发布垃圾产品时才会使用的。
在 Cocoa 时代,这是无法想象的。在 Mac OS X 的早期阶段,这种情况甚至会是一场灾难。你能想象一个 SwiftUI 版本的经典 Aqua 发布会吗?
想象一下,如果当年乔布斯没有展示那些看起来如此精美、甚至“让人想舔一下”的液态按钮,而是展示闪烁的侧边栏和不断跳动的按钮。他恐怕会被彻底嘲笑。
但现在,似乎我们正在接受“够用”的产品,以及“差不多就行”的心态。这种对于工艺品质的标准,我无法接受。
而且,这并不只是某一个框架的问题。这是一次系统性的变化。
最开始,一家公司提出“快速行动,打破常规”的理念。渐渐地,越来越多开发者加入其中。他们并不一定真的都在快速行动,但发布存在缺陷的产品,开始变得正常起来——甚至连第一方应用和系统组件也不例外。
比如,Apple Music 多年来一直存在一个 Bug:编辑播放队列时,歌曲列表会突然跳动,然后播放完全错误的歌曲。
TestFlight 会裁剪截图选择区域,而且没有任何边距。
iPad 上的设置应用会显示各种崩溃报告。
主屏幕会显示同一个应用的重复图标,状态栏会来回跳动,它还会显示一些本不应该出现的图标轮廓。
甚至像 Logic Pro 这样的专业应用,如今也会带着缺失的本地化内容发布。你知道的,就是那些本应该成为质量和稳定性标杆的专业应用。
我可以继续列举很多例子。
虽然这些问题并不全部都使用 SwiftUI,但它们反映出了苹果如今认为“可以接受”的质量标准。我并没有费很大力气去寻找这些问题;它们只是我过去几个月里亲眼遇到的事情。
所以,考虑到这些例子后,旗舰级系统框架让开发者几乎无法构建一个完全没有问题的应用,也就不足为奇了。
尤其是在苹果平台上,这种变化大约始于 2018 年,也就是我前面提到的那些“格格不入”的应用出现的时候。那时,Project Marzipan(后来更名为 Catalyst)首次允许开发者将 UIKit 代码复用于 Mac 平台。科技媒体纷纷批评这些应用的表现。
但苹果并没有选择重新打磨这些基础工作,反而进一步强化了跨平台开发的理念,并推出了 SwiftUI。而这个全新的、未经充分验证的框架,又带来了更多性能、稳定性以及视觉体验方面的问题。
我的结论是:降低质量标准是一种选择,而不是迫不得已的结果。我拒绝接受这种选择。这也是为什么,即使过去七年,SwiftUI 依然无法让我完全信任。
![]()
总结
最后,回到开头提出的问题:SwiftUI 到底出了什么问题?
如果把它存在七年时间里那些始终没有解决的问题全部考虑进去,答案就是:
一切。
或者至少,是构建稳定、高性能、可维护系统时最重要的那些部分。
SwiftUI 的故事,是一个关于平庸化和标准降低的故事。我们被要求用可预测的精确性,去交换一种虚假的便利。然后,我们被迫在两种选择之间做决定:要么花大量时间调试框架本身,要么就这样发布一个存在问题的应用。
作为一名资深工程师,我对这两个选择都没有兴趣。我无法认同“差不多能用就行”的心态,我认为用户值得拥有比“足够好”更好的产品。
SwiftUI 并不是一个真正糟糕的框架。它只是平庸。而在我看来,这反而糟糕得多。
所以,至少目前,我依然更倾向于使用那些“遗留”的 UI 框架。
![]()
后记
多年来,我一直在观察 SwiftUI 努力成为 AppKit 和 UIKit 的可靠替代品——换句话说,成为苹果早在 2019 年承诺它会成为的那个样子。
这些年来,我不断测试 SwiftUI 的每一次新版本,希望那些长期困扰它的问题最终能够得到解决。
但随着时间推移,SwiftUI 并没有在根本上变得更好。它依然像七年前一样不够成熟,而使用 SwiftUI 构建的应用,大多数也依然表现得平淡无奇。
但我观察的不只是 SwiftUI 的困境。我也一直在观察那些真心认为“只要一个 SwiftUI 功能现在能正常工作,那自己的任务就完成了”的软件工程师。
除非他们是故意选择了更差的工具,否则我其实并不完全责怪他们。
好吧,也许还是有一点。因为你无法忽视长期维护成本,而不为此付出代价。
不过,通常情况下,真正承担这个代价的并不是这些工程师个人,而是他们所在的公司。但在如今这个企业热衷于用 AI Agent 替代人类的时代,很难期待这些企业生产出的产品质量会有所提升。而这些企业,往往也是那些把软件开发视为一种商品化流程,或者线性生产过程的公司。
他们通常追求的是“快速交付”,而不是“正确交付”。我们已经开始看到这种做法带来的结果,而未来还会看到更多。
GOSIM SHENZHEN 2026 全球开源 AI 大会
10 月 16—17 日 · 深圳
150+ 国内外讲师 · 2000+ 全球开发者 · Agentic AI
开源大模型 / 开源机器人 / 边缘智能体 / 智能体操作系统
Keynote + Workshop + Hackathon + AI Vision Forum
早鸟限时抢购中
扫码购票,锁定你的 AI 盛会席位!
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.