这是我目前拥有的代码。基本上,我想有一个可选的ViewBuilder添加一个条件视图,让说一个附件视图。在一种.overlay
语法中,你可以有也可以没有覆盖。但是在插入视图时,我得到了这个错误Cannot convert value of type '' to closure result type 'Content'
public struct MyView<Content: View>: View {
@State var isHidden: Bool = false
// stuff here
let content: (Int) -> Content
var additionalView: (() -> Content)?
public init(@ViewBuilder content: @escaping (Int) -> Content, additionalView: (() -> Content)? = nil) {
self.content = content
self.additionalView = additionalView
}
public var body: some View {
VStack(spacing: 0) {
ZStack {
content(selection)
}
// more stuff
if !isHidden {
if let additionalView {
additionalView()
}
// Another view
}
}
}
public func accessoryView(@ViewBuilder content: @escaping () -> Content) -> some View {
var view = self
view.additionalView = content
return view
}
}
最后我想这样称呼它。
struct MyMainView<Content: View>: View {
@StateObject var appInfo: AppInfo = AppInfo()
@ViewBuilder let content: (Int) -> Content
var body: some View {
VStack(spacing: 0) {
MyView(content: content)
.accessoryView {
AnyKindOfView()
// This is where it fails with "Cannot convert value of type 'AnyKindOfView' to closure result type 'Content'"
}
.onAppear {
//code
}
}
.environmentObject(appInfo)
}
}
我错过了什么?我试图创建一个额外的,<AdditionalContent: View>但它似乎不工作。
1条答案
按热度按时间rta7y2nd1#
您确实应该使用一个额外的类型参数来标识附件视图的类型。附件视图不一定与
Content
相同。这就是一些内置SwiftUI视图的设计方式,比如Label
有两个类型参数来表示标题和图标。请注意,可选参数使Swift很难推断
Accessory
类型,所以我删除了它,并在Accessory == Never
的扩展中添加了一个单参数init
。同样,这类似于SwiftUI的内置视图与可选视图构建器的工作方式。例如,不接受label
视图构建器的Button
初始化器在扩展中声明,其中Label == Text
。对于
accessoryView
修饰符,它也需要是通用的。它应该返回一个新的MyView
,带有一个不同的Accessory
类型参数。不过,我觉得没这个必要。为什么不直接将视图传递给初始化器的
additionalView
参数呢?另一种方法是使用
AnyView
作为附件视图的类型。这涉及到使init
的通用以及。