swift - ForEach 在一系列协议实现上?
问题描述
我开始学习 SwiftUI,所以我决定编写一个简单的密码管理器作为学习练习。我protocol
在我的密码中定义了一个通用属性:
protocol Secret: Codable {
var id: String { get set }
var name: String { get set }
var createdDate: Date { get set }
var favorite: Bool { get set }
var category: SecretCategory { get set }
var notes: String { get set }
init(_ id: String, name: String)
init(_ id: String, name: String, favorite: Bool)
}
然后,我定义了几个 Swiftstruct
来实现它protocol
并定义各种类型的秘密的属性:
struct LoginSecret: Secret, Identifiable {
var id: String
var name: String
var createdDate: Date = Date()
var favorite: Bool = false
var category: SecretCategory = .login
var notes: String = ""
var username: String = ""
var encryptedPassword: String = ""
var websiteURLs: [String] = []
init(_ id: String, name: String) {
self.id = id
self.name = name
}
init(_ id: String, name: String, favorite: Bool) {
self.id = id
self.name = name
self.favorite = favorite
}
}
...和...
struct BankAccountSecret: Secret, Identifiable {
var id: String
var name: String
var createdDate: Date = Date()
var favorite: Bool = false
var category: SecretCategory = .bankAccounts
var notes: String = ""
var bankName: String = ""
var nameOnAccount: String = ""
var routingNumber: String = ""
var accountNumber: String = ""
var swift: String = ""
var iban: String = ""
var encryptedPIN: String = ""
var branchPhoneNumber: String = ""
var branchAddress: Address = Address()
init(_ id: String, name: String) {
self.id = id
self.name = name
}
init(_ id: String, name: String, favorite: Bool) {
self.id = id
self.name = name
self.favorite = favorite
}
}
这些工作正常,我可以在 JSON 中编码/解码值以便稍后显示。但是,现在我正在编写我的 SwiftUI 代码。我想在一个中显示每个项目,使用SwiftUIList
对一个对象进行迭代。我的代码如下所示:Array
Secret
ForEach
struct SecretsListView: View {
@State
var secrets: [Secret]
var body: some View {
NavigationView {
List {
ForEach(secrets) { secret in
<snip>
}
}
}
}
}
但是,当我编译时,我收到一条错误消息...
Value of protocol type 'Secret' cannot conform to 'Identifiable'; only struct/enum/class types can conform to protocols
有没有办法遍历Secret
对象数组?有没有不同的方法来实现这一点?这个问题是 SwiftUI 特有的ForEach
吗?我应该改用标准的 SwiftArray
forEach
方法吗?非常感谢您提供的任何指导。我使用 Swift 和 UIKit 已经有一段时间了,但是 SwiftUI 是新的,我想确保我正在为框架进行正确的开发。
解决方案
是的,只SwiftUI.ForEach
需要Identifiable
一致性,Array.forEach
不需要它。
虽然还有其他几个初始化器ForEach
不需要您的模型类型符合Identifiable
.
例如,您可以使用init(_ data: Data, id: KeyPath<Data.Element, ID>, content: @escaping (Data.Element) -> Content)
(假设ID
符合Hashable
,Secret.id
确实如此,因为它是 a String
)。
ForEach(secrets, id: \.id) { secret in
<snip>
}
另一种解决方案是将数组的索引传递给ForEach
,然后您可以使用ForEach(secrets.indices)
,但是由于您有一个可以用作的Hashable
属性,因此前一个是更好的解决方案。Secret
id
推荐阅读
- python - 在 Python 中的数据框中排列组内的元素
- angularjs - 如何查找过滤器的原因:notarray 错误
- sql - Pgadmin 错误:无法打开文件读取:权限被拒绝
- javascript - 触发 Reacter Router 时如何执行函数
- python - 看不到任何打印的东西
- onnx - 如何从其他 ONNX 模型中获取权重
- flutter - 提供商无法重建主屏幕
- salesforce - 如何理解 @TestClass Apex 代码与嵌入在 Map 中的列表
- javascript - 基于数据库的 Cron 调度
- python - Python引发异常,其中消息具有回车\ r控制字符