如果我正确理解你的问题,这就是你正在寻找的:
struct FullButton<Label>: View where Label: View {
var action: () -> Void
var label: () -> Label
var body: some View {
Button(action: self.action, label: self.label)
}
}
这将允许您传递想要在按钮上显示的任何内容,这意味着您此处的代码现在可以工作:
FullButton(action: {
print("touched")
}) {
Text("Button")
}
Update
多次查看您的问题后,我意识到您的困惑源于对创建正常情况时发生的事情的误解Button
.
在下面的代码中,我正在创建一个Button
。该按钮有两个参数 -action
and label
.
Button(action: {}, label: {
Text("Button")
})
如果我们查看文档Button
,我们看到它是这样声明的:
struct Button<Label> where Label : View
如果我们查看初始化器,我们会看到:
init(action: @escaping () -> Void, @ViewBuilder label: () -> Label)
Both action
and label
预计关闭。action
期望一个返回类型为Void
, and label
期望一个@ViewBuilder
返回类型为的闭包Label
。正如声明中所定义的Button
, Label
是一个泛型,代表一个View
,所以真的,label
期待一个返回 a 的闭包View
.
这并不是独一无二的Button
. Take HStack
, 例如:
struct HStack<Content> where Content : View
init(alignment: VerticalAlignment = .center, spacing: Length? = nil, @ViewBuilder content: () -> Content)
Content
在这里有同样的目的Label
确实在Button
.
还有其他需要注意的事情 - 当我们创建这样的按钮时......
Button(action: {}) {
Text("Button")
}
...我们实际上正在做同样的事情:
Button(action: {}, label: {
Text("Button")
})
在 Swift 中,当方法调用中的最后一个参数是闭包时,我们可以省略参数标签并将闭包附加到右括号的外部。
在 SwiftUI 中,您不能将内容隐式传递给任何View
. The View
必须明确接受@ViewBuilder
其初始化程序中的闭包。
所以,你不能通过@ViewBuilder
关闭到FullButton
unless FullButton
接受一个@ViewBuilder
闭包作为其初始值设定项中的参数,如我的答案开头所示。