• 原文地址:SwiftUI in 2021: The Good, the Bad, and the Ugly
  • 原文作者:Chrys Bader
  • 译文出自:翻译方案
  • 本文永久链接:github.com/xitu/gold-m…
  • 译者:earthaYan
  • 校对者:Lokfar、lsvih、jaredliw

2021 年的 SwiftUI: 优势、下风和缺陷

在出产环境运用 SwiftUI?依然不可行。

过去的 8 个月,我一向在用 SwiftUI 开发杂乱的运用程序,其间就包括最近在 App Store 上架的 Fave。期间遇到了很多限制,也找到了大多数问题的处理办法。

简而言之,SwiftUI 是一个很棒的框架,而且极具远景。我以为它便是未来。可是要达到和 UIKit 平等的可靠性和健壮性,或许还需求 3-5 年。可是这并不意味着现在不应该运用 SwiftUI。我的意图是协助你了解它的利害,这样你能够就 SwiftUI 是否合适下一个项目做出更正确的决议。

SwfitUI 的优势

1. 编写 SwiftUI 是一件乐事,而且你能够快速构建用户界面

运用 addSubviewsizeForItemAtIndexPath,小心谨慎地计算控件的巨细与方位,应对烦人的束缚问题,手动构建视图层次结构,这样的日子现已一去不复返了。SwiftUI 的声明式和呼应式设计形式使得创立呼应式布局和 React 一样简略,一起它还背靠 Apple 强壮的 UIKit。用它构建、启动并运转视图快到难以想象。

2. SwiftUI 简化了跨渠道开发

我最兴奋的工作便是只需求编写一次 SwiftUI 代码,就能够在 iOS (iPhone 和 iPad),WatchOS 和 macOS 上运用。一起开发和保护 Android 和 Windows 各自的代码库现已很困难了,所以在削减不同代码库的数量这方面,每一个小的改变都很有协助。当然仍是有一些缺陷,我将会在 “下风” 章节共享。

3. 你能够免费获取漂亮的转场作用,动画和组件

你能够把 SwiftUI 当作一个 UI 工具箱,这个工具箱提供了开发专业运用程序所需的一切构建块。另外,假如你熟悉 CSS 的 Transition 特点,你会发现 SwiftUI 也有一套相似的办法,能够轻松创立优雅的交互过程。声明式语法的魅力在于你只需求描述你需求什么样的作用,作用就完成了,这看上去像魔法一样,可是也有欠好的一面,我之后将会介绍。

4. UI 是完全由状况驱动而且是呼应式的

假如你熟悉 React 的话,SwiftUI 在这一点上完全相似。当你监听整个 UI 的”反应“,动画和一切一切的时分,你只需求修正 @State@Binding 以及 @Published 特点,而不是运用多达几十层的嵌套回调函数。运用 SwiftUI,你能够体会到 CombineObservableObject 以及 @StateObject 的强壮。这方面是 SwiftUI 和 UIKit 最酷的差异之一,强壮到难以想象。

5. 社区正在拥抱 SwiftUI

简直每个人都在因为 SwiftUI 而兴奋。SwiftUI 有许多学习资源可供获取,从 WWDC 到书,再到博客 —— 材料就在那里,你只需求去查找它。假如不想查找的话,我这儿也汇总了一份最佳社区资源列表。

具有一个活泼且支撑度高的社区能够加速学习,开发,而且很多的新库会使得 SwiftUI 用处更加广泛。

下风

1. 不是一切组件都能够从 SwiftUI 中获取到

在 SwiftUI 中有许多缺失、不完整或者过于简略的组件,我将在下面详细介绍其间一部分。

运用 UIViewRepresentableUIViewControllerRepresentableUIHostingController 协议能够处理这一问题。前两个让你能够在 SwiftUI 视图层中嵌入 UIKit 视图和控制器。最后一个能够让你在 UIKit 中嵌入 SwiftUI 视图。在 Mac 开发中也存在相似的三种协议 (NSViewRepresentable 等)。

这些协议是弥补 SwiftUI 功用缺失的权宜之计,但并不是一向天衣无缝。而且,虽然 SwiftUI 的跨渠道承诺很好,可是假如某些功用不可用的话,你依然需求为 iOS 和 Mac 别离完成协议代码。

2. NavigationView 还没有真实完成

假如你想在隐藏导航栏的一起依然支撑滑动手势,这是不或许的。我终究参阅一些找到的代码创立了一个 UINavigationController wrapper。虽然能够起作用,但这不是一个长远的处理方案。

假如你想要在 iPad 上具有一个 SplitView,但现在你还不能以纵向形式一起展示主视图和详情视图。他们挑选用一个简陋的按钮展示默许封闭的抽屉。显然,你能够经过添加 padding 来处理这个问题,它能够突出显现你在运用 SwiftUI 时有必要做的工作。

当你想运用编程式导航的时分,NavigationLink 是一种盛行的处理方案。这儿有一个有趣的评论。

3. 文本输入十分受限

TextFieldTextEditor 现在都太简略了,终究你仍是会退回到 UIKit。所以我不得不为 UITextFieldUITextView 构建自己的 UIViewRepresentable 协议(以完成文本行数的自动增加)。

4. 编译器困境

当视图开端变得笨重,而且你现已竭尽所能去提取分化,编译器依然会冲着你咆哮:

The compiler is unable to type-check this expression in reasonable time; try breaking up the expression into distinct sub-expressions.

这个问题现已屡次拖慢进展。因为这个问题,我现已很拿手注释代码定位到引起问题的那一行,可是 2021 年了还在用这种办法调试代码感觉十分落后。

5. matchedGeometryEffect

我第一次发现这个的时分,感觉很奇特。它意图是经过匹配一隐一现的几许形状,协助你更加流畅地转化两个不同标识的视图。我觉得这有助于从视图 A 优雅地转场到 B 视图。

我一向想让它起作用。但终究仍是放弃了,因为它并不完美。此外,在包括很多列表项的 ListScrollView 中运用它会导致项目瘫痪。我只推荐在同一视图中运用这个做简略的转化过渡。当你在多个不同的视图中共享一个命名空间的时分(包括转场期间的视图取舍在内),工作就会开端变得古怪。

6. 对手势的支撑有限

SwiftUI 提供了一系列新的手势(即 DragGestureLongPressGesture)。这些手势能够经过 gesture 修饰符(如 tapGesturelongPressGesture)添加到视图中。它们都能正常工作,除非你想要做更杂乱的交互。

比如,DragGestureScrollView 交互就不是很好。即便有了 simultaneousGesture 修饰符,在 ScrollView 中放一个 DragGesture 仍是会阻挠翻滚。在其他情况下,拖动手势能够在没有任何告诉的情况下被取消,使得手势处于不完整状况。

为了处理这个问题,我构建了自己的 GestureView,它能够在 SwiftUI 中运用 UIKit 手势。我会在下一篇关于最佳 SwiftUI 库和处理方案的文章中共享这部分内容。

7. 共享扩展中的 SwiftUI

我或许是错的,可是共享扩展仍是运用 UIKit 吧。我经过 UIHostingController 用 SwiftUI 构建了一个共享扩展,当共享扩展加载完毕后,有一个十分显着的推迟,用户体会较差。你能够尝试经过在视图中添加动画去掩盖它,可是依然有 500 毫秒左右的推迟。

值得一提的点

  • 无法访问状况栏 (不能修正色彩或拦截点击)
  • 因为短少 App,咱们依然需求 @UIApplicationDelegateAdaptor
  • 不能向后兼容
  • UIVisualEffectsView 会导致翻滚推迟(来源于推特:@AlanPegoli)

缺陷

1. ScrollView

这是迄今为止最大的缺陷之一。任何一个构建过定制化 iOS 运用的人都知道咱们有多依靠 ScrollView 去支撑交互。

  • 首要的障碍:视图中的 LazyVStack 导致卡顿、抖动和一些意外的行为。LazyVStack 对于需求翻滚的混合内容(如新闻提要)的长列表至关重要。仅凭这一点,SwiftUI 就还没预备好投入出产环境: Apple 现已证明,这是 SwiftUI 本身的缝隙。尚未清楚他们什么时分会修正,可是一旦修正了,这将是一个巨大的胜利。
  • 翻滚状况:原生不支撑解析翻滚的状况(翻滚视图是否正在被拖拽?翻滚?偏移多少?)。虽然有一些处理方案,可是仍是很繁琐且不稳定。
  • 分页:原生不支撑分页翻滚视图。所以打消完成相似于可滑动的媒体库的念头吧(可是假如你想要封闭一些东西的时分,能够运用 SwiftUIPager)。在技术上你能够运用 TabViewPageTabViewStyle,可是我以为它更合适少部分的元素,而不是大的数据集。
  • 功能:运用 List 是功能最好的,而且避免了 LazyVStack 的卡顿问题,但因为工作方法的转化,它依然不合适显现可变巨细的内容。例如,在构建聊天视图时,其过渡很古怪,会裁剪子视图,而且无法控制刺进的动画样式。

结论

毫无疑问我觉得应该学习 SwiftUI ,自己去了解它,并享用趣味。可是先别急着全盘采用。

SwiftUI 现已为简略的运用程序做好了预备,可是在写这篇文章的时分(iOS 15,beta 4 版别),我不以为它现已合适杂乱运用程序的出产环境,首要是因为 ScrollView 的问题和对 UIViewRepresentable 的严峻依靠。我很惋惜,尤其是像即时通讯产品,新闻摘要,以及严峻依靠杂乱视图或者想要创立手势驱动的定制体会产品,现在还不合适运用 SwiftUI。

假如你想要精细的控制和无限的或许性,我建议在可预见的未来坚持运用 UIKit。你能够在一些视图(如设置页)里经过运用 UIHostingController 包装 SwiftUI 视图以获得 SwiftUI 的好处。

未来会产生什么?

当开端着手咱们项意图下一次大迭代的时分。我知道这个新项意图交互规模不在 SwiftUI 现在支撑的规模之内。即便当我知道 SwiftUI 在某些关键方面存在不足的时分,我的心都碎了,可是我仍是不方案退回到 UIKit,因为我知道当 SwiftUI 运转起来时,构建它是一件多么快乐的工作。它的速度如此之快。

SwiftUI 会兼容 UIKit 么?假如这样的话,咱们或许需求等候 SwiftUI 运用 3-5 年的时刻来移植一切必要的 UIKit API。假如 SwiftUI 不预备兼容 UIkit,那你也能经过 SwiftUI 封装的方法运用 UIKit。

我好奇的是 Apple 会在 SwiftUI 上投入多少。他们是否有让一切的开发者采用 SwiftUI 的长时间方案,或者说 SwiftUI 只是另一个界面构建器而已?我期望不是,也期望他们能全心投入 SwiftUI,因为它的远景是十分诱人的。

更多看法

  • Is SwiftUI Ready?
  • SwiftUI Drawbacks: Why SwiftUI Is Not Ready for Production Yet
  • My takeaway from working with SwiftUI

假如发现译文存在过错或其他需求改善的地方,欢迎到 翻译方案 对译文进行修正并 PR,也可获得相应奖励积分。文章最初的 本文永久链接 即为本文在 GitHub 上的 MarkDown 链接。


翻译方案 是一个翻译优质互联网技术文章的社区,文章来源为 上的英文共享文章。内容覆盖 Android、iOS、前端、后端、区块链、产品、设计、人工智能等范畴,想要检查更多优质译文请持续关注 翻译方案、官方微博、知乎专栏。