如何在不继承 SwiftUI 中其他已定义视图的情况下制作正文,苹果最初是如何做到的?
Posted
技术标签:
【中文标题】如何在不继承 SwiftUI 中其他已定义视图的情况下制作正文,苹果最初是如何做到的?【英文标题】:How can I make body without inheriting from other defined View in SwiftUI, How apple done this at first place? 【发布时间】:2021-03-21 01:17:40 【问题描述】:我喜欢学习和学习不使用继承来创建视图,例如为了显示我的目标,我创建了一个名为 Color2 的新类型视图,它按预期工作,但实际上它继承自明确定义的 Color,所以如果我想让 Color2 独立,而不是从任何我必须创建或返回 body 的东西继承,否则 Color2 不会被 SwiftUI 编译!这更像是一个老问题先有鸡还是先有蛋?
Apple 如何让 Color 一开始就独立存在甚至存在? Apple 在做 Color View 的时候,也应该想到 Color 的本体!但是苹果只是在创造颜色,他们甚至不能像我在代码中那样继承! 因为没有要继承的颜色视图!!!
所以 问题/问题 是如何在没有符合 View 的 reference/defined View 的情况下返回 body ? (看!我想在没有鸡的情况下创建鸡蛋)
这段代码可以正常工作,它们只是伪代码:
struct ContentView: View
var body: some View
Color2.red
enum Color2 case red, black
extension Color2: View
public var body: some View
switch self
case Color2.red: Color.red // <<: Here: how can I return a View if I want not using defined View!
case Color2.black: Color.black // <<: Here: how can I return a View if I want not using defined View!
【问题讨论】:
【参考方案1】:所以问题/问题是如何在没有符合 View 的引用/定义 View 的情况下返回 body ?
你不能。
作为 SwiftUI 的用户,您可以这样做:
您可以通过实现body
方法来创建符合View
的类型。
您创建符合View
的类型实例并将它们传递给函数或从函数返回。
这是你不做的事情:
您不会向View
询问其body
。
SwiftUI 框架向View
询问其body
。你永远不会。
诀窍在于 SwiftUI 不会总是向 View
询问其 body
。
SwiftUI 知道一些特定的“原始”View
类型。当 SwiftUI 需要渲染(或布局)原始 View
时,它会识别出 View
是原始类型并对其进行特殊处理,无需询问原始 View
的 @987654334 @。
如果Body
是Never
,则View
类型是原始类型。我怎么能确定这一点?因为返回Never
类型的值是不可能!没有这样的价值观。所以,如果View
的body
返回Never
,我知道SwiftUI 不可能要求View
为其body
,所以SwiftUI 必须 对待@987654344 @ 不同于“正常”View
。
例如,Text
、Image
和 Color
都是 SwiftUI 原语:
1> import SwiftUI
2> Text.Body.self
$R0: Text.Body.Type = Never
3> Image.Body.self
$R1: Image.Body.Type = Never
4> Color.Body.self
$R2: Color.Body.Type = Never
另一方面,Rectangle
不是原语,但它的 body
返回一个未记录的原语:
5> Rectangle.Body.self
$R3: Rectangle.Body.Type = _ShapeView<Rectangle, ForegroundStyle>
6> _ShapeView<Rectangle, ForegroundStyle>.Body.self
$R4: _ShapeView<Rectangle, ForegroundStyle>.Body.Type = Never
您无法实现自己的原始 View
类型,因为您无权访问识别和处理原始 View
类型的 SwiftUI 实现细节。
【讨论】:
谢谢,我试过这个:import SwiftUI, Color.Body.self 然后 xcode 抱怨 are not allowed at top level,那么你在哪里找到那些代码?如果我们不允许运行这些代码,为什么它们存在? 我在 Swift REPL 中运行了我的示例:xcrun swift
从命令行。您也可以使用 Playground 进行测试。
所以用英语苹果说并允许我们自己从已经定义的视图中创建视图,换句话说,我们可以从视图中创建视图,但是我们不能像我尝试的那样定义一个全新的视图.这样说对吗?
我得到了答案,非常感谢,关于这个话题的最后一个问题!我认为我们也不允许使用原语,甚至将我们的自定义原语定义为 Xcode/SwiftUI 的用户,这被锁定并且只允许苹果本身,对吗?
您不能定义自己的原始View
类型。您只能编写现有的 View
类型。【参考方案2】:
一切都必须从某个地方开始。因此,您可以从 View 开始并撰写,如
https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-and-compose-custom-views
或者你可以包装一个 UIView,如
https://www.hackingwithswift.com/quick-start/swiftui/how-to-wrap-a-custom-uiview-for-swiftui
要求更低的级别就是下拉到屏幕的像素级别,根本没有框架,这是没有意义的。您是框架的用户,而不是框架的作者。
【讨论】:
那么你的回答就是说 SwiftUI 只不过是一个包装好的 UIView?!让我这么说吧:如果我们想创建一个 View,我们应该使用 SwiftUI 中定义的 View 或 Wrap a UIView,也就是说,SwiftUI 中的每一件事都只是一个 Wrapped UIView,从 Color 到 Text,从 VStack 到 Circle ?因为没有Color View可以参考!或者没有文本视图来引用它,等等。 . 不,我不是这么说的。 是的,你是说,你说在 SwiftUI 中有两种创建视图的方法! 1- 使用定义的视图 2- 使用包装的 UIView。想一想:Apple 想要为我们创建和构建 Color View 以便在 SwiftUI 中使用它,好吗?那么 Apple 只需使用包装好的 UIView 选项就可以了!因为 Apple 不能在 SwiftUI 中引用 Color View,因为它不存在!以上是关于如何在不继承 SwiftUI 中其他已定义视图的情况下制作正文,苹果最初是如何做到的?的主要内容,如果未能解决你的问题,请参考以下文章
SwiftUI |如何覆盖 viewWillAppear 等生命周期方法