33

我正在尝试使用新的SwiftUI框架从枚举中列出案例的原始值。但是,我在将“数据”符合可识别协议时遇到了麻烦,我真的找不到如何做到这一点的信息。它告诉我“Initializer 'init(_:rowContent:)' 要求 'Data' 符合 'Identifiable'” 存根在最后一个扩展中为我提供了一个 ObjectIdentifier 变量,但不知道我应该返回什么。你能告诉我怎么做吗?如何使 Data 符合 Identifiable,以便我可以使用原始值制作一个列表?

enum Data: String {
    case firstCase = "First string"
    case secondCase = "Second string"
    case thirdCase = "Third string"
}

extension Data: CaseIterable {
    static let randomSet = [Data.firstCase, Data.secondCase]
}

extension Data: Identifiable {
    var id: ObjectIdentifier {
        return //what?
    }

}

//-------------------------ContentView------------------------
import SwiftUI

struct Lala: View {
    var name: String

    var body: some View {
        Text(name)
    }
}

struct ContentView: View {
    var body: some View {
        return List(Data.allCases) { i in
            Lala(name: i.rawValue)
        }
    }
}
4

3 回答 3

72

⚠️ 尽量不要使用已经使用过的名称,例如Data您的内部模块。我将MyEnum在这个答案中使用


当某些东西符合 时Identifiable,它必须返回可以被它识别的东西。因此,您应该返回该案例独有的内容。对于Stringbase enumrawValue您拥有的最佳选择是:

extension MyEnum: Identifiable {
    var id: RawValue { rawValue }
}

此外,enums 通常可以自己识别:

extension MyEnum: Identifiable {
    var id: Self { self }
}

⚠️ 注意 1:如果返回不稳定的东西,例如UUID()索引,这意味着每次获取对象时都会得到一个新对象,这会破坏可重用性,并可能导致视图管理之外的史诗般的内存和布局进程使用过渡管理等问题。

看看这个添加新宠物的奇怪动画: UUID 示例

注意 2:从 Swift 5.1 开始,单行闭包不需要return关键字。

注意 3:尽量不要使用全球知名的名称,例如Data您自己的类型。至少使用命名空间MyCustomNameSpace.Data


内联模式

您可以通过其中一个元素的键路径使任何集合可迭代内联:

例如self

List(MyEnum.allCases, id:\.self)

或任何其他兼容的密钥路径:

List(MyEnum.allCases, id:\.rawValue)

✅ 标识符的清单:(来自WWDC21)

  • 谨慎使用随机标识符。
  • 使用稳定的标识符。
  • 确保唯一性,每个项目一个标识符。
于 2019-08-08T11:30:09.663 回答
5

具有关联值的另一种方法是执行类似的操作,其中所有关联值都是可识别的。

enum DataEntryType: Identifiable {
    var id: String {
        switch self {
        case .thing1ThatIsIdentifiable(let thing1):
            return thing1.id
        case .thing2ThatIsIdentifiable(let thing2):
            return thing2.id
        }
    }
    
    case thing1ThatIsIdentifiable(AnIdentifiableObject)
    case thing2ThatIsIdentifiable(AnotherIdentifiableObject)
于 2021-10-15T13:24:24.550 回答
4

你可以这样试试:

enum MyEnum: Identifiable {
    case valu1, valu2
    
    var id: Int {
        get {
            hashValue
        }
    }
}
于 2020-12-25T05:15:44.410 回答