【问题标题】:SwiftUI creating a dictionary to hold different viewsSwiftUI 创建一个字典来保存不同的视图
【发布时间】:2020-08-09 21:37:52
【问题描述】:

我正在尝试构建一个非常简单的 SwiftUI 程序来轻松交换视图。目标是尽可能简单地添加更多视图,而无需更改确定哪个视图的代码(因此标准的if-else 不起作用)。

我目前的想法是保留一个字典,其中包含作为键值对的一部分存储的视图。一个非常基本的实现示例如下:

import SwiftUI

struct ViewA: View {
  var body: some View {
    Text("This is View A")
  }
}

struct ViewB: View {
  var body: some View {
    Text("This is View B")
  }
}

struct MainView: View {
  
  var subviews: [String:View] = [
    "View-1": ViewA(),
    "View-2": ViewB(),
  ]
  
  var body: some View {
    self.subviews["View-1"]
  }
}

但是,我在创建字典的行中遇到错误:Protocol 'View' can only be used as a generic constraint because it has Self or associated type requirements

我已经为字典的值部分尝试了许多不同的类型,包括AnyViewGroups,并在 MainView 结构上创建了一个泛型类型<Content: View>。然而,这些会产生更多/不同的错误。

我查看了SwiftUIRouter 项目,因为它解决了我想要实现的目标,但我的目标更加简单。

提前致谢。

【问题讨论】:

  • AnyView 应该可以工作,但您需要将任何视图包装在 AnyView(ViewA()) 中以存储它。
  • 谢谢!唯一的问题是我读到 AnyView 效率不高。您认为它会以明显的方式影响性能吗?
  • 我的理解是,如果所有视图都只是AnyView 类型(而不是通过不透明some View 实现的确切类型),SwiftUI 不会知道哪个视图树分支不需要被重新计算。但是如果你需要一个类似路由器的功能,需要使用完全不同的视图层次结构,我认为你不可避免地需要使用AnyView

标签: swift generics swiftui


【解决方案1】:

Swift 没有命名下标,因此您必须将其组合在一起,但您可以使用相同的调用语法以及其他有用/更好的语言功能:

struct MainView: View {
  var body: some View {
    subviews["View-1"]
  }
  
  enum subviews {
    @ViewBuilder static subscript(string: String) -> some View {
      switch string {
      case "View-1":
        ViewA()
      case "View-2":
        ViewB()
      default:
        fatalError()
      }
    }
  }
}

【讨论】:

  • 谢谢@Jessy,但我不太同意你的看法。您将在 Swift 中创建一个字典,其中键是字符串或任何其他类型。您只需像我上面那样使用字典语法。 developer.apple.com/documentation/swift/dictionary
  • 对不起,我不明白你的措辞。您似乎认为我不知道 Dictionary 类型是什么。
猜你喜欢
  • 2021-06-28
  • 2020-01-26
  • 2014-06-17
  • 2017-08-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多