我需要在这样的结构中有一个VStack
作为属性
struct Str
{
let view: VStack
....
}
编译器说:
“对泛型类型'VStack‘的引用需要<...>中的参数
插入“<<#Content:View#>>”
“
Xcode "fix“生成:
struct Str
{
let view: VStack<Content: View>
...
}
但是编译器仍然抱怨:
“预期complete >‘>完成泛型参数列表”
是否允许在结构中有一个VStack?
发布于 2020-02-21 20:48:25
您所发现的是,VStack
并不是真正的类型。我们可以更准确地将其描述为“类型构造函数”。声明如下:
struct VStack<Content> where Content : View {
...
}
你给它一些其他类型作为它的Content
参数,它给你一个类型。给它类型Text
,然后返回类型VStack<Text>
。给它类型Image
,然后返回类型VStack<Image>
。你得到的类型是不同的类型!VStack<Text>
类型的对象是,而不是,类型是VStack<Image>
。
所以你只需要知道哪种类型可以作为论点,对吗?问题是 of SwiftUI“type”实际上是泛型类型构造函数。所以类型变得复杂了。下面是我正在开发的一个应用程序的一个例子:
var body: some View {
VStack(spacing: 0) {
scene
if store.model.latestError != nil {
Divider()
ErrorView(store: errorStore)
.padding(20)
}
} //
.frame(width: 450)
}
body
的类型是什么?我可以在运行时打印它以找出:
print(type(of: AppView(store: store).body))
输出是
ModifiedContent<VStack<TupleView<(AnyView, Optional<TupleView<(Divider, ModifiedContent<ErrorView, _PaddingLayout>)>>)>>, _FrameLayout>
请注意,body
返回的对象类型公开了许多关于body
实现的详细信息。例如,由于ErrorView
有一个padding
修饰符,body
对象的类型包括ModifiedContent<ErrorView, _PaddingLayout>
。我可以在不更改类型的情况下将填充量从20更改为30。但是如果完全删除padding
修饰符,它就会更改类型(通过将ModifiedContent<ErrorView, _PaddingLayout>
更改为仅ErrorView
)。
那你怎么解决这个问题?一种方法是使用AnyView
struct Str {
let view: AnyView
...
}
let str = Str(view: AnyView(VStack {
...
}))
请注意,有时您会听到关于应该避免使用AnyView
的建议。下面是乔·格罗夫解释原因的说明:
您可以使用AnyView包装器显式包装类型,在那里它们可以动态更改。 然而,动画系统将有一个更容易的时间,如果你可以按下视图图尽可能。您可以有一种布局类型,采用
.portrait
/.landscape
,以不同的方式应用旋转、平移等,然后转换就可以动画化了。
https://stackoverflow.com/questions/60345648
复制相似问题