如何在Swift中确认可识别协议的枚举?

Ата*_*ков 4 enums ios swiftui swift5.1

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

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)
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Moj*_*ini 11

当某物符合时Identifiable,它必须返回可以被该物识别的东西。因此,您应该返回该情况下唯一的东西。对于Stringbase enumrawValue是您的最佳选择:

extension Data: Identifiable {
    var id: String { rawValue }
}
Run Code Online (Sandbox Code Playgroud)

枚举通常也可以通过自身来标识:

extension Data: Identifiable {
    var id: Data { self }
}
Run Code Online (Sandbox Code Playgroud)

注意1:如果返回的东西总是唯一的,例如UUID,这意味着每次获取对象时都会得到一个新对象,这将杀死可重用性,并可能导致史诗般的内存和布局过程使用。

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

注3:尽量不要使用诸如Data您自己的类型之类的全局已知名称。至少像这样使用命名空间MyCustomNameSpace.Data

内联模式

您可以通过元素的键路径之一使任何集合内联成为可迭代的:

例如self

List (Data.allCases, id:\.self)
Run Code Online (Sandbox Code Playgroud)

或任何其他兼容的键路径:

List (Data.allCases, id:\.rawValue)
Run Code Online (Sandbox Code Playgroud)


Dr.*_*cle 6

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

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)
Run Code Online (Sandbox Code Playgroud)


Olc*_*taş 5

你可以尝试这样的方法:

enum MyEnum: Identifiable {
    case valu1, valu2
    
    var id: Int {
        get {
            hashValue
        }
    }
}
Run Code Online (Sandbox Code Playgroud)