本文介绍了可选的@ViewBuilder 闭包的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
在 SwiftUI 中是否可以有一个可选的 @ViewBuilder
闭包?例如,假设我想开发一个自定义视图,它需要两个视图构建器闭包,如下所示:
Is it possible in SwiftUI to have an optional @ViewBuilder
closure? For example, let's say I want to develop a custom view that takes two view builder closures like this:
import SwiftUI
struct TopAndBottomView<Content>: View where Content: View {
let topContent: () -> Content
let bottomContent: () -> Content
init(@ViewBuilder topContent: @escaping () -> Content, @ViewBuilder bottomContent: @escaping () -> Content) {
self.topContent = topContent
self.bottomContent = bottomContent
}
var body: some View {
VStack {
topContent()
Spacer()
bottomContent()
}
}
}
struct TopAndBottomView_Previews: PreviewProvider {
static var previews: some View {
TopAndBottomView(topContent: {
Text("TOP")
}, bottomContent: {
Text("BOTTOM")
})
}
}
但我希望底部视图是可选的.我试过:
But I'd like the bottom view to be optional. I tried with:
struct TopAndBottomView<Content>: View where Content: View {
let topContent: () -> Content
let bottomContent: (() -> Content)?
init(@ViewBuilder topContent: @escaping () -> Content, @ViewBuilder bottomContent: (() -> Content)? = nil) {
self.topContent = topContent
self.bottomContent = bottomContent
}
var body: some View {
VStack {
topContent()
Spacer()
if bottomContent != nil {
bottomContent!()
}
}
}
}
但我收到此错误:
函数构建器属性ViewBuilder"只能应用于函数类型参数.
谢谢.
推荐答案
考虑到 ViewBuilder
的 buildIf
特性,以下方法是可能的,允许保留 init
中的 ViewBuilder(最好)
Taking into account buildIf
feature of ViewBuilder
the following approach is possible that allows to keep ViewBuilder
in init
(that is preferable)
经过测试适用于 Xcode 11.2/iOS 13.2
Tested & works with Xcode 11.2 / iOS 13.2
struct TopAndBottomView<Content>: View where Content: View {
let topContent: () -> Content
let bottomContent: () -> Content?
init(@ViewBuilder topContent: @escaping () -> Content,
@ViewBuilder bottomContent: @escaping () -> Content? = { nil }) {
self.topContent = topContent
self.bottomContent = bottomContent
}
var body: some View {
VStack {
topContent()
Spacer()
bottomContent()
}
}
}
就像这个一样
struct TopAndBottomView_Previews: PreviewProvider {
static var previews: some View {
TopAndBottomView(topContent: {
Text("TOP")
}, bottomContent: {
Text("BOTTOM")
})
}
}
还有这个
struct TopAndBottomView_Previews: PreviewProvider {
static var previews: some View {
TopAndBottomView(topContent: {
Text("TOP")
})
}
}
这篇关于可选的@ViewBuilder 闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!