Fatbobman's Swift Weekly #132
From OpenSwiftUI to DanceUI: Another Way to Dive into SwiftUI

From OpenSwiftUI to DanceUI: Another Way to Dive into SwiftUI
Counting from its debut in 2019, SwiftUI is approaching its seventh year. It has long shed its initial growing pains and gradually become one of the foundational skills for developers in the Apple ecosystem. However, SwiftUI’s closed-source nature also means that many of its underlying mechanisms remain opaque. While developers can certainly feel its expressive advantages when using it, it’s often difficult to trace the root cause once a problem occurs. This characteristic also puts SwiftUI at a bit of a disadvantage in the era of AI-assisted programming—compared to technologies that have long been exposed in community discussions, source codes, and documentation, the high-quality materials available for large models to reference are ultimately limited.
Because of this, the community has always hoped to replicate SwiftUI through open-source projects: on the one hand, to give this excellent design a chance to run on more platforms; on the other hand, to gain a better understanding of SwiftUI’s internal mechanisms through the replication process. In recent years, the most highly-watched project in this regard is undoubtedly OpenSwiftUI. Driven continuously by the community, it has already filled in some of the core implementations of SwiftUI and made experimental explorations on platforms outside the Apple ecosystem. Although it obviously still has a long way to go to reach its goal, it remains one of the most important gateways for developers today to understand SwiftUI’s internal mechanisms.
Actually, besides the community, some companies—even very large ones—have also conducted in-depth research and replication of SwiftUI over the past few years. Last week, ByteDance open-sourced their SwiftUI replication project, DanceUI.
I first heard about this project in 2022. What surprised me the most at the time wasn’t “someone is replicating SwiftUI,” but rather, “why is ByteDance doing this?” Later, after communicating with the developers involved in this project, I roughly understood their motives: on one hand, they wanted to gain stronger control when introducing declarative development into their massive product ecosystem; on the other hand, they hoped to grasp key capabilities like runtime, dependency graphs, and host integration in their own hands by studying excellent frameworks like SwiftUI. Compared to OpenSwiftUI, DanceUI looks less like a community-driven replica and more like a sample of reverse-engineering SwiftUI driven by practical engineering needs.
More importantly, over the past few years, DanceUI has already entered production environments in some product modules within ByteDance. This means it is clearly not just an experimental toy, but a set of development tools that have withstood a certain level of testing in terms of performance and stability. For SwiftUI developers, it therefore provides another gateway to understanding SwiftUI.
Of course, such projects shouldn’t be over-glorified. They are not SwiftUI itself, nor do they represent Apple’s official implementation. Projects like OpenSwiftUI, which are strongly research- and compatibility-oriented, naturally have clear boundaries; while projects like DanceUI carry an obvious background of large-tech internal engineering and practical application. Neither should be treated as the sole source of “SwiftUI truth.”
However, this does not prevent them from being excellent learning materials. None of them are SwiftUI, yet they can all help us get closer to it. Diving into SwiftUI by following open-source projects is essentially not about finding an “open-source alternative,” but rather using these projects to train our own way of understanding SwiftUI.
Previous Issue|Newsletter Archive
📢 Sponsor Fatbobman’s Swift Weekly
Promote your product to Swift & iOS developers across:
- Blog: 50,000+ monthly visitors
- Newsletter: 4,000+ subscribers, 53% open rate
Perfect for developer tools, courses, and services.
Enjoyed this issue? Buy me a coffee ☕️
Recent Recommendations
Interface Segregation Principle In IOS: How To Prevent A Protocol From Becoming A Prison
Many developers have likely experienced a similar trajectory: a carefully designed small protocol in the early stages of a project gradually evolves into an unwieldy “monster” as team collaboration and business requirements grow. Pawel Kozielecki illustrates this through a progressively bloated UserService, showing how fat protocols introduce testing overhead, hidden coupling, and significant refactoring costs. Beyond proposing a practical approach based on smaller protocols and incremental migration, the article highlights a deeper issue: the real danger often lies not in a single flawed design decision, but in a series of seemingly reasonable “let’s just add this here for now” choices.
In the era of AI-assisted programming, this problem can be further amplified. Large models tend to infer semantics from file and protocol names, and vague or overly broad naming naturally attracts more loosely related responsibilities. Clear, precise, and restrained naming is no longer just a matter of style—it increasingly defines system boundaries.
Animating Strikethroughs in SwiftUI
How would you animate a strikethrough or underline in SwiftUI Text? A common first instinct is to use an overlay with Shape. However, this approach struggles with Dynamic Type and multi-line text. Ashli Rankin presents a more systematic solution: leveraging the TextRenderer API introduced in iOS 17 to access Text.Layout internals (lines, glyphs, etc.), and using a progress value accumulated across lines to draw a continuous, animatable strikethrough. By conforming to Animatable, SwiftUI can smoothly interpolate state changes.
An interesting detail: TextField does not use the same rendering pipeline as Text, so TextRenderer cannot be applied directly. The workaround involves overlaying a transparent Text (for rendering the animation) on top of a real TextField, combined with a custom Layout to enforce consistent wrapping width, ultimately resolving multi-line alignment issues.
Checking accessibility with SwiftUI Previews
SwiftUI Previews are typically used to verify UI layout, but they can also help validate certain aspects of accessibility during development. Rob Whitaker outlines several practical approaches: using Xcode Canvas to quickly toggle light/dark mode, orientation, and Dynamic Type, or defining specific environments via Preview Traits.
The article also highlights some private environment properties available only in Previews (such as increased contrast, reduced motion, or inverted colors), which can be enabled via underscored key paths. These must be restricted to #if DEBUG to avoid leaking private APIs into production builds.
A UIKit Project’s SwiftUI Migration: A Practical Retrospective
Yusuke Hosonuma reflects on his experience working on a UIKit + RxSwift + Coordinator project and gradually migrating most of its UI to SwiftUI over the course of a year. Rather than focusing on implementation details, the article centers on real-world engineering trade-offs: how a small team, with minimal communication and almost no documentation, can maintain long-term evolvability through continuous delivery, incremental replacement, and intentionally simple design.
The author also offers grounded reflections on common practices, such as being cautious with protocol abstraction, EnvironmentObject, premature generalization, and the urge to “clean up everything” during migration. This is less a technical guide and more a realistic retrospective on team practices and engineering judgment.
Cancelling SwiftUI Animations: What Actually Works (And Why)
Stopping an in-flight repeatForever animation in SwiftUI is not as straightforward as it seems. Using .none or disabling animations via Transaction only affects new animations, not those already running in the rendering system. Codelaby provides a working solution: defining a custom CustomAnimation that returns nil from animate (signaling immediate completion), and using shouldMerge to take over the current animation, effectively cancelling it.
SwiftUI performs interpolation based on state changes and animation functions. “Stopping” an animation is essentially replacing it with a new state transition that takes control, rather than interrupting the existing animation.
Tools
Swift Institute: Rebuilding the Swift Ecosystem as a Solo Effort
An astonishing project discovered by chance. Over the past nine months, Coen ten Thije Boonkkamp has made nearly 9,800 commits, single-handedly building a Swift ecosystem of almost 300 packages across three layers: primitives, standards, and foundations. The goal is to realize his proposed Modern Swift Library Architecture: dependencies flow downward, integration happens outside core types, and “test what you own, trust what you import.”
One person, one idea, explored and validated with AI. Whether it ultimately succeeds or not, this is exactly the kind of exploration that demonstrates the real value of AI.
swift-ast-lint: Writing Swift Lint Rules in Swift
Developed by Ryu, swift-ast-lint is not another SwiftLint, but a custom linting infrastructure built on SwiftSyntax. It is designed for teams that need AST-level rules, filling the gap where regex-based approaches fall short.
The project supports scaffolding, parameterized rules, path filtering, and --fix auto-correction. It is well-suited for enforcing architectural constraints, code organization, and module boundaries—areas where regex is unreliable. While not ideal for out-of-the-box use, it is a strong option for teams with established conventions who want to formalize them as tooling.
As AI-assisted development becomes more common, the real value may lie not only in generation, but in how we encode and enforce team constraints.
Event
Swift Craft 2026
Swift Craft is a community-driven iOS / Apple platform developer conference taking place May 18–20 in Folkestone, UK. The schedule is already available, covering topics across Swift, SwiftUI, and application architecture.
Compared to larger conferences, Swift Craft focuses more on small-scale, in-depth discussions and emphasizes a strong community atmosphere. One notable detail is the venue: Leas Cliff Hall, perched on a seaside cliff with floor-to-ceiling windows overlooking the English Channel—an environment that naturally enhances the overall experience.
The organizers are offering a discount code FBM26 (£50 off Indie tickets) for readers of this newsletter. If you’re considering attending a developer event in Europe, you can check the details via the Swift Craft tickets page.
Thanks for reading Fatbobman’s Swift Weekly! This post is public so feel free to share it.
从 OpenSwiftUI 到 DanceUI:换个方式 Dive SwiftUI
从 2019 年问世算起,SwiftUI 已经快七年了。它早已脱去了最初几年的稚气,逐渐成为苹果生态开发者的基础能力之一。不过,SwiftUI 的闭源属性也意味着,它的很多运行机制始终不透明。开发者在使用时固然能感受到它的表达优势,但一旦遇到问题,往往很难进一步追踪原因。这种特性也让 SwiftUI 在 AI 辅助编程时代显得有些“吃亏”——相比那些长期暴露在社区讨论、源码和文档中的技术,大模型能参考的高质量材料终究有限。
也正因此,社区一直希望通过开源项目去复刻 SwiftUI:一方面,是希望让 SwiftUI 这套优秀的设计有机会运行在更多平台上;另一方面,也是希望借助复刻过程,对 SwiftUI 的内部机制获得更多理解。最近几年,这方面最受关注的项目无疑是 OpenSwiftUI。在社区持续推进下,它已经补齐了 SwiftUI 的一部分核心实现,并在苹果生态之外的平台上做出了一些实验性探索。虽然距离它的目标显然还有不短的路要走,但它依然是当下开发者理解 SwiftUI 内部机制的重要入口之一。
其实,除了社区之外,一些公司,甚至规模很大的公司,也在过去几年里做过对 SwiftUI 的深入研究和复刻。上周,字节跳动开源了他们的 SwiftUI 复刻项目 DanceUI。
我第一次听说这个项目是在 2022 年。当时最让我感到意外的,不是“有人在复刻 SwiftUI”,而是“为什么是字节跳动在做这件事”。后来陆续和参与这个项目的开发者交流后,我大致理解了他们的动机:一方面,他们希望在将声明式开发引入庞大产品体系时获得更强的控制力;另一方面,也希望借由对 SwiftUI 这类优秀框架的研究,把运行时、依赖图和宿主整合等关键能力握在自己手里。和 OpenSwiftUI 相比,DanceUI 更不像一个社区式复刻项目,而更像一套从工程落地出发、反向拆解 SwiftUI 的样本。
更重要的是,过去几年中,DanceUI 已经在字节内部的一些产品模块中进入了生产环境。这意味着它显然不只是一个实验性的玩具,而是一套在性能和稳定性上都经受过一定检验的开发工具。对于 SwiftUI 开发者来说,它也因此提供了另一个理解 SwiftUI 的入口。
当然,这类项目并不适合被简单神化。它们不是 SwiftUI 本身,也不代表苹果官方实现。尤其像 OpenSwiftUI 这样带有强烈研究和兼容性导向的项目,本身就有明确边界;而像 DanceUI 这样的项目,则带着明显的大厂内部工程背景和落地取向。它们都不应该被当成“SwiftUI 真相”的唯一来源。
但这并不妨碍它们成为很好的学习材料。它们都不是 SwiftUI,却都能帮助我们更接近 SwiftUI。跟着开源项目去 dive SwiftUI,本质上不是在找一个“开源替代品”,而是在借这些项目训练自己理解 SwiftUI 的方式。
如果您发现这份周报或我的博客对您有所帮助,可以考虑通过 爱发电,Buy Me a Coffee 支持我的创作。
近期推荐
别让协议变成“怪物”:iOS 中的接口隔离实践 (Interface Segregation Principle In IOS: How To Prevent A Protocol From Becoming A Prison)
很多开发者可能都经历过类似的过程:项目早期一个精心设计的小协议,随着团队协作与业务演进,逐渐膨胀为难以维护的“怪物”。Pawel Kozielecki 通过一个逐步失控的 UserService 案例,具体展示了胖协议如何在团队协作中引入测试负担、隐性耦合,以及难以推进的重构成本。作者不仅给出了基于小协议组合与渐进迁移的现实方案,也点出了问题的根源:真正危险的,往往不是一次明显的设计失误,而是一连串“这次先加进去也没关系”的合理决定。
在 AI 辅助编程日益普及的背景下,这一问题反而更容易被放大。大模型倾向于依据文件名、协议名进行语义推断,一个模糊或过于宽泛的命名,往往会自然地吸引更多“不那么相关”的职责被不断叠加进去。清晰、准确且克制的命名,正在从代码风格问题,逐渐演变为影响系统边界的重要因素。
为 Text 实现删除线动画 (Animating Strikethroughs in SwiftUI)
为 SwiftUI Text 的删除线或下划线实现动画效果?不少人第一反应可能是基于 overlay + Shape 的方案。不过,这种方式很难正确适配 Dynamic Type 以及多行文本场景。Ashli Rankin 展示了一条更“系统化”的路径:基于 iOS 17 引入的 TextRenderer,直接访问 Text.Layout 的内部结构(行、glyph 等),并通过一个 progress 值在所有行之间累计绘制,从而实现连续、可动画的删除线效果。同时通过实现 Animatable,让 SwiftUI 在状态变化时自动完成插值过渡。
一个更有意思的细节在于:TextField 并不会走 Text 的渲染流程,因此 TextRenderer 无法直接应用。作者通过叠加一个透明的 Text(负责绘制动画)与真实的 TextField,并结合自定义 Layout 强制两者使用一致的换行宽度,最终解决了多行错位问题。
在 SwiftUI 预览中验证可访问性 (Checking accessibility with SwiftUI Previews)
SwiftUI Previews 通常用于检查界面布局,但同样可以在开发阶段快速验证部分可访问性(Accessibility)表现。Rob Whitake 梳理了几种常用途径:例如通过 Xcode Canvas 直接切换深浅色、方向、Dynamic Type 等进行快速检查,或借助 Preview Traits 定义特定的预览环境。文章还提到了一些仅用于 Preview 的私有环境变量(如增强对比度、减少动画、颜色反转等),通过带下划线的 keyPath 可以强制开启这些状态。不过需要注意,这类 API 必须限制在 #if DEBUG 中使用,以避免私有符号进入最终构建,带来审核风险。
一个 UIKit 项目的 SwiftUI 迁移实录
Yusuke Hosonuma 回顾了自己参与一个 UIKit + RxSwift + Coordinator 项目,并在一年多时间里逐步完成大部分界面 SwiftUI 化的经历。文章聚焦于真实项目中的工程取舍:在小团队、低沟通、几乎无文档的条件下,如何通过持续交付、渐进替换与尽量简单的设计,让项目保持可演进性。作者对不少常见做法都给出了很有现实感的反思,例如谨慎对待 protocol 抽象、EnvironmentObject、过早共通化,以及“顺手清理一切旧架构”的冲动。这并非单纯的技术实现总结,而是一篇充满真实感的团队实践复盘。
如何停止一个运行中的 SwiftUI 动画 Cancelling SwiftUI Animations: What Actually Works (And Why)
在 SwiftUI 中,停止一个已经运行的 repeatForever 动画并不像想象中那么简单。无论是使用 .none,还是通过 Transaction 禁用动画,都只能影响新的动画,而无法中断已经存在于渲染系统中的动画。Codelaby 给出了一个可行方案:通过自定义 CustomAnimation,让 animate 返回 nil(表示立即完成),并通过 shouldMerge 接管当前动画,从而实现终止动画的效果。
SwiftUI 会基于状态变化与动画函数自动进行插值计算。所谓“停止”,本质上是用一个新的状态变化去接管当前动画,而不是中断之前的动画。
工具
Swift Institute: 一个人的 Swift 基础设施重写
偶然看到的一个让我震惊的项目。Coen ten Thije Boonkkamp 在过去 9 个月里提交了约 9800 次 git commit,独自构建了一个分为 primitives、standards、foundations 三层、累计近 300 个包的 Swift 生态。目标只有一个——落地他去年提出的 Modern Swift Library Architecture 思想:依赖只能向下、集成发生在核心类型之外、”test what you own, trust what you import”。
一个人、一个构想,通过 AI 来进行尝试、验证。无论最后是否成功,但这是我想看到的 AI 意义。
swift-ast-lint:用 Swift 写 Swift 代码检查规则
由 Ryu 开发的 swift-ast-lint 不是另一个 SwiftLint,而是一套基于 SwiftSyntax 的自定义 lint 基础设施。它更适合需要编写 AST 级规则的团队,用来补足正则匹配在结构化检查上的局限。
项目支持脚手架生成、参数化规则、路径过滤以及 --fix 自动修复,比较适合处理架构约束、代码组织、模块边界等 regex 很难可靠覆盖的问题。它不太适合只想开箱即用的用户,但对于已经有明确工程规范、又希望把这些规范工具化的 Swift 团队来说,是一个值得关注的项目。
在 AI 辅助开发越来越普遍之后,真正有价值的可能不只是生成能力本身,还包括如何把团队规范和结构约束工具化。
活动
Swift Craft 2026
Swift Craft 是一个由社区驱动的 iOS / Apple 平台开发者大会,将于 5 月 18–20 日在英国 Folkestone 举行。目前议程已经公布,涵盖 Swift、SwiftUI 以及应用架构等多个方向。
相比大型会议,Swift Craft 更偏向小规模与深度交流,也更强调开发者之间的社区氛围。一个有趣的细节是本次会议的场地:位于海边悬崖上的 Leas Cliff Hall,会场三面落地窗直面英吉利海峡,这种环境本身就足以让会议体验变得与众不同。
主办方为本周报读者提供了折扣码 FBM26(£50 off Indie 票)。如果你有参与线下开发者活动的计划,可以通过 Swift Craft tickets page 了解详情。

