SwiftUI 中类型的可组合性

Posted

技术标签:

【中文标题】SwiftUI 中类型的可组合性【英文标题】:Composability with types in SwiftUI 【发布时间】:2019-07-03 14:14:07 【问题描述】:

我们的目标是创建一个表,其中行是不同类型的,每一个都是一个“组件”。所以想象一下 Apple 教程中的 LandmarkRow,但我们也将展示住宿而不是地标。我想让每个组件都有自己的组件,这部分很简单。

更具挑战性的部分是我如何从每个视图中获取视图(如果它们在一个集合中)。理想的情况是,如果它们都实现了协议,然后我可以将它们放在包含该协议的类型集合中,然后只调用常用方法,例如构建视图。问题是不透明类型似乎破坏了继承。如果我在基类中创建 build() -> some View 方法,则在派生类中提供实现不会被视为覆盖。所以我没有得到派生的。相反,现在,我只是在表视图主体中的每种类型的 item 为 Landmark 时做。

为了非常清楚,我不想要一个 switch 或一个 if 语句块,这是 OO 101:我们应该能够派生一个实现协议的新类型,然后将该类型添加到集合中表是由什么组成的。

我们确实发现我们可以强制将视图强制转换为协议,然后调用该方法,这是可行的。优点是每次添加新视图时都不必编辑开关或 if 阻塞,但仍然不必要/不正确。

【问题讨论】:

【参考方案1】:

由于您需要它们都返回相同的类型(符合View 的类型),您可能希望它们都返回AnyView

【讨论】:

做到了,但问题是,根据我可能不完美的描述,它只是调用基类方法,并说覆盖不适用.. 如果您需要更多帮助,您将需要编辑您的问题以包含一些代码。【参考方案2】:

事实证明,Apple 确实为此提供了解决方案,但不是在示例中,而是在“所有设备上的 SwiftUI”会话中。大约 26 分钟,他们讨论了提供 2 个不同的 LandmarkRow 实现,但他们不使用继承。他们使用泛型和 lambda。资源中没有这方面的代码,但您可以在会话中看到它。

【讨论】:

以上是关于SwiftUI 中类型的可组合性的主要内容,如果未能解决你的问题,请参考以下文章

使用 XCUIElementQuery 在 SwiftUI 中查找嵌入在表单中的 DatePicker() 的可访问性(标识符:)

使用 XCTestCases 类中的可访问性标识符访问 NavigationLink - SwiftUI

如何使用适当的可访问性修饰符覆盖 SwiftUI Picker

有啥方法可以在 SwiftUI 中的可搜索导航修饰符上关闭自动更正/设置键盘类型

SwiftUI-> 线程 1:致命错误:未找到 MyObject.Type 类型的可观察对象(工作表中的 EnvironmentObject)

SwiftUI 中的可选状态或绑定