- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在努力解决一个问题,我认为(希望)有一个简单的解决方法,您或许可以提供帮助。
我正在尝试对多个变量运行 ForEach
循环。为了简单起见,我只包含了两个变量,但还有更多变量,因此我想使用 ForEach
循环而不是为每个变量重复相同的代码。每个变量都基于不同的枚举。
我想在我的代码中运行一个 ForEach 循环,循环遍历变量数组并提取变量的描述和关联的原始值。
var profileEyeColor: EyeColor = EyeColor()
var profileHairColor: HairColor = HairColor()
enum EyeColor: String, CaseIterable {
case notSet
case amber
case blue
case brown
case gray
case green
case hazel
case other
case witheld
var description: String {
"Eye Color"
}
init() {
self = .notSet
}
}
enum HairColor: String, CaseIterable {
case notSet
case black
case blond
case brown
case auburn
case red
case gray
case white
case other
case witheld
var description: String {
"Hair Color"
}
init() {
self = .notSet
}
}
ForEach([profileEyeColor, profileHairColor], id: \.self) { item in
if item != .notSet && item != .witheld {
print(item.description)
print(item.rawValue)
}
}
构建失败并且 xCode 错误包括:
我尝试使用 for
循环而不是 ForEach
来运行。我正在使用 SwiftUI,因此无法在正文中实现 for
循环。我也试过将它拆分成一个单独的函数,但在函数上出现错误。
func profileDetailsLoop(data: [Any]) -> View {
ForEach(data, id: \.self) { item in
if item != .notSet && item != .witheld {
HStack {
Text(item.description)
Text(item.rawValue)
}
}
}
错误:协议(protocol)类型“Any”的值不符合“Hashable”;只有结构/枚举/类类型可以符合协议(protocol)
如果我用 [enum]
替换 [Any]
那么我会收到以下错误:Expected element type
如果我将 [Any]
替换为任何特定的枚举类型,例如 [EyeColor]
将不起作用(并且大概也不会处理不同的枚举类型)。
最佳答案
ForEach
有一定的要求,它喜欢迭代 Identifiable
项的集合。考虑到这一点,让我们提供一个 struct Attribute
,每个属性都可以提供:
struct Attribute: Identifiable {
let name: String
let value: String
let id = UUID()
}
您可以手动向提供此属性的每个枚举添加一个计算变量,但这会产生大量重复代码。
相反,让我们注意所有的属性都提供一个rawValue
和一个description
,这就是初始化一个Attribute
真正需要的全部.
定义这个协议(protocol):
protocol AttributeType {
var rawValue: String { get }
var description: String { get }
}
然后为返回属性
的协议(protocol)创建此扩展
:
extension AttributeType {
var attribute: Attribute? {
guard self.isSet else { return nil }
return Attribute(name: self.description, value: self.rawValue)
}
var isSet: Bool { return !["notSet", "witheld"].contains(self.rawValue) }
}
最后,让您的所有枚举都采用AttributeType
:
enum EyeColor: String, CaseIterable, AttributeType {
case notSet
case amber
...
var description: String {
"Eye Color"
}
init() {
self = .notSet
}
}
enum HairColor: String, CaseIterable, AttributeType {
case notSet
case black
...
var description: String {
"Hair Color"
}
init() {
self = .notSet
}
}
然后您可以通过访问 .attribute
属性为每个属性获取一个 Attribute
。
ForEach([profileEyeColor.attribute, profileHairColor.attribute].compactMap { $0 }) { attribute in
HStack {
Text(attribute.name)
Text(attribute.value)
}
}
为避免为数组中的每个 属性键入.attribute
,您可以这样写:
ForEach([profileEyeColor as AttributeType, profileHairColor].compactMap { $0.attribute }) {
这将为长属性列表节省大量输入。
注意事项:
.attribute
返回一个可选 Attribute
。如果属性为 .notSet
或 .witheld
,则为 nil
。.compactMap { $0 }
用于删除 nil
值并为 ForEach
创建一个 [Attribute]
> 迭代。Attribute
是Identifiable
,它提供了 id
,因此没有必要明确说明这一点。关于swift - ForEach 循环遍历不同的变量类型 swift,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64303442/
我是一名优秀的程序员,十分优秀!