[英]SwiftUI generics used from second initialiser
I am looking to structure a SwiftUI component in a similar way as some of Apple's implementations (Eg Button).我希望以与 Apple 的某些实现(例如按钮)类似的方式构建 SwiftUI 组件。 I am looking to have a label associated to this component (which is just another View) or have the ability to construct using just a string (and default to using a Text view).
我希望有一个 label 与该组件相关联(这只是另一个视图),或者能够仅使用字符串进行构造(并且默认使用文本视图)。
This is what I have:这就是我所拥有的:
struct ExampleComponent<Label> : View where Label : View {
let label: () -> Label
let action: () -> ()
init(_ title: String, action: @escaping () -> ()) {
self.init(label: {
Text(title)
}, action: action)
}
init(@ViewBuilder label: @escaping () -> Label, action: @escaping () -> ()) {
self.label = label
self.action = action
}
var body: some View {
label()
}
}
However, this cannot compile due to the error:但是,由于错误,这无法编译:
Cannot convert value of type 'Text' to closure result type 'Label'.
无法将“文本”类型的值转换为闭包结果类型“标签”。
What's going wrong?怎么了?
If you want this to be a default, then you need to make sure it only applies in cases where Label == Text
.如果您希望这是默认设置,那么您需要确保它仅适用于
Label == Text
的情况。 In other situations, you can't use it.在其他情况下,您不能使用它。 I generally do this with a constrained extension:
我通常使用受限扩展来执行此操作:
extension ExampleComponent where Label == Text {
init(_ title: String, action: @escaping () -> ()) {
self.init(label: {
Text(title)
}, action: action)
}
}
But you can also add the constraint on the init
directly:但是你也可以直接在
init
上添加约束:
init(_ title: String, action: @escaping () -> ()) where Label == Text {
self.init(label: {
Text(title)
}, action: action)
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.