- 原文地址: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 是一件乐事,而且你能够快速构建用户界面
运用 addSubview
和 sizeForItemAtIndexPath
,小心谨慎地计算控件的巨细与方位,应对烦人的束缚问题,手动构建视图层次结构,这样的日子现已一去不复返了。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,你能够体会到 Combine
、ObservableObject
以及 @StateObject
的强壮。这方面是 SwiftUI 和 UIKit 最酷的差异之一,强壮到难以想象。
5. 社区正在拥抱 SwiftUI
简直每个人都在因为 SwiftUI 而兴奋。SwiftUI 有许多学习资源可供获取,从 WWDC 到书,再到博客 —— 材料就在那里,你只需求去查找它。假如不想查找的话,我这儿也汇总了一份最佳社区资源列表。
具有一个活泼且支撑度高的社区能够加速学习,开发,而且很多的新库会使得 SwiftUI 用处更加广泛。
下风
1. 不是一切组件都能够从 SwiftUI 中获取到
在 SwiftUI 中有许多缺失、不完整或者过于简略的组件,我将在下面详细介绍其间一部分。
运用 UIViewRepresentable
、UIViewControllerRepresentable
和 UIHostingController
协议能够处理这一问题。前两个让你能够在 SwiftUI 视图层中嵌入 UIKit 视图和控制器。最后一个能够让你在 UIKit 中嵌入 SwiftUI 视图。在 Mac 开发中也存在相似的三种协议 (NSViewRepresentable
等)。
这些协议是弥补 SwiftUI 功用缺失的权宜之计,但并不是一向天衣无缝。而且,虽然 SwiftUI 的跨渠道承诺很好,可是假如某些功用不可用的话,你依然需求为 iOS 和 Mac 别离完成协议代码。
2. NavigationView 还没有真实完成
假如你想在隐藏导航栏的一起依然支撑滑动手势,这是不或许的。我终究参阅一些找到的代码创立了一个 UINavigationController wrapper。虽然能够起作用,但这不是一个长远的处理方案。
假如你想要在 iPad 上具有一个 SplitView,但现在你还不能以纵向形式一起展示主视图和详情视图。他们挑选用一个简陋的按钮展示默许封闭的抽屉。显然,你能够经过添加 padding 来处理这个问题,它能够突出显现你在运用 SwiftUI 时有必要做的工作。
当你想运用编程式导航的时分,NavigationLink
是一种盛行的处理方案。这儿有一个有趣的评论。
3. 文本输入十分受限
TextField
和 TextEditor
现在都太简略了,终究你仍是会退回到 UIKit。所以我不得不为 UITextField
和 UITextView
构建自己的 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 视图。
我一向想让它起作用。但终究仍是放弃了,因为它并不完美。此外,在包括很多列表项的 List
或 ScrollView
中运用它会导致项目瘫痪。我只推荐在同一视图中运用这个做简略的转化过渡。当你在多个不同的视图中共享一个命名空间的时分(包括转场期间的视图取舍在内),工作就会开端变得古怪。
6. 对手势的支撑有限
SwiftUI 提供了一系列新的手势(即 DragGesture
和 LongPressGesture
)。这些手势能够经过 gesture
修饰符(如 tapGesture
和 longPressGesture
)添加到视图中。它们都能正常工作,除非你想要做更杂乱的交互。
比如,DragGesture
和 ScrollView
交互就不是很好。即便有了 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
)。在技术上你能够运用TabView
加PageTabViewStyle
,可是我以为它更合适少部分的元素,而不是大的数据集。 -
功能:运用
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、前端、后端、区块链、产品、设计、人工智能等范畴,想要检查更多优质译文请持续关注 翻译方案、官方微博、知乎专栏。