【问题标题】:SwiftUI polymorphic behaviour not working for ViewSwiftUI 多态行为不适用于 View
【发布时间】:2022-11-25 06:06:10
【问题描述】:
protocol BackgroundContent: View{
}
struct BlueDivider: BackgroundContent {
var body: some View {
Divider()
.frame(minHeight: 1)
.background(.blue)
}
}
struct RedDivider: BackgroundContent {
var body: some View {
Divider()
.frame(minHeight: 1)
.background(.red)
}
}
var p: BackgroundContent = BlueDivider()
// Use of protocol 'BackgroundContent' as a type must be written 'any BackgroundContent'
p = RedDivider()
这总是要求我使用
var p: any BackgroundContent = BlueDivider()
有什么方法可以使用通用的输入哪个接受任何一种观点?
实际上,我想使用视图作为状态,如 @State private var bgView: BackgroundContent = BlueDivider(),我想在运行时更改,如bgView = RedDivider()
通过使用此状态,我已经使我的自定义视图在运行时放置一些其他视图。
【问题讨论】:
标签:
swift
generics
swiftui
swift-protocols
【解决方案1】:
对于你的具体问题,你可以在这里做这样的事情:
struct SwiftUIView: View {
@State var isRed = false
var body: some View {
Devider()
.frame(height: 1)
.background(isRed ? Color.red : Color.blue)
}
}
【解决方案2】:
这很复杂,但我找到了解决这个问题的方法。我对 ObservableObject 所做的第一件事。这是我的例子。
protocol BaseBackgroundContent {
var color: Color { get set }
}
class BlueContent: BaseBackgroundContent {
var color: Color = .blue
}
class RedContent: BaseBackgroundContent {
var color: Color = .red
}
在这种情况下,我为 Divider 创建了一个自定义视图。
struct CustomDivider: View {
var backgroundContent: any BaseBackgroundContent
var body: some View {
Divider()
.background(backgroundContent.color)
}
}
现在我使用了一个可以观察到的 viewModel,并且必须发布协议。
class ExampleViewModel: ObservableObject {
@Published var backgroundContent: any BaseBackgroundContent = RedContent()
func change() {
backgroundContent = BlueContent()
}
}
最后一步是视图。这是一个示例视图。如果单击该按钮,您将看到 BlueContent,它是 RedContent
struct Example: View {
@ObservedObject var viewModel = ExampleViewModel()
init() {
}
var body: some View {
VStack {
Text("Test")
CustomDivider(backgroundContent: viewModel.backgroundContent)
Button("Change") {
viewModel.change()
}
}
}
}