如何在 Swift 中确认对 Identifiable 协议的枚举?

Posted

技术标签:

【中文标题】如何在 Swift 中确认对 Identifiable 协议的枚举?【英文标题】:How to confirm an enumeration to Identifiable protocol in Swift? 【发布时间】:2019-12-16 00:00:08 【问题描述】:

我正在尝试使用新的 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)
        
    

【问题讨论】:

也许这会有所帮助:***.com/questions/24011170/… 【参考方案1】:

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


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

extension MyEnum: Identifiable 
    var id: RawValue  rawValue 

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

extension MyEnum: Identifiable 
    var id: Self  self 

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

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

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

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


内联模式

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

例如给self:

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

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

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

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

谨慎使用随机标识符。 使用稳定的标识符。 确保唯一性,每个项目一个标识符。

【讨论】:

您能否详细说明为什么 UUID 会降低性能? 不会的!每次返回 一个新的 UUID 将强制引擎构建一个全新的组件,而不是重用旧的。 知道了,感谢您的澄清。是否有任何文档说明 SwiftUI 如何使用传入的 id 来确定视图是否需要失效/创建/重新创建? id 必须是唯一的 per 唯一数据。您只需传递数据并让渲染引擎决定它是否需要无效/创建/重新创建的对象。我认为您应该搜索“列表”和“标识符”及其文档。 @PeterKaminski 我知道这在您撰写此评论时不存在,但对于未来的任何人来说也是如此 - 查看揭秘 SwiftUI WWDC21 会议here。【参考方案2】:

你可以试试这个方法:

enum MyEnum: Identifiable 
    case valu1, valu2
    
    var id: Int 
        get 
            hashValue
        
    

【讨论】:

【参考方案3】:

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

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)

【讨论】:

完美运行,谢谢!

以上是关于如何在 Swift 中确认对 Identifiable 协议的枚举?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Swift 中确认订单后发送电子邮件

如何在 Swift 中使用警报视图解除 segue?

如何在 swift 中使用其他类()委托和数据源函数?

如何在 swift 中添加与 UIAlertController 的 textField 一起使用的“基本类型”?

在swift UI中点击按钮时如何更改背景颜色和图像?

如何在 Django 中使用引导模式对表数据进行删除确认?