【问题标题】: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()
                  }
              }
          }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-11-05
        • 2015-01-20
        • 1970-01-01
        相关资源
        最近更新 更多