首页 > 解决方案 > SwiftUI 允许 Struct 中的所有字符串枚举

问题描述

这可能是一个愚蠢的问题,但我试图允许所有字符串枚举作为 Struct 中变量的类型。下面的代码是完全错误的,但我希望它能让我的问题更清楚。

我的想法是使所有枚举符合相同的协议,但我无法使用这种方法访问 .allCases 。

我的目标是我可以将任何字符串枚举传递给 ListView,然后它将显示枚举的所有组件(这里:一;二;三)。

有谁知道如何做到这一点?它一定是一个非常基本的 Swift 东西,但我无法通过网络搜索找到它。太感谢了!

import SwiftUI

struct ContentView: View {
    
    var body: some View {
        ListView(myEnum: Elements.self) //error here as well
    }
}

protocol StringRepresentable {
    var rawValue: String { get }
}

enum Elements: String, Equatable, CaseIterable, StringRepresentable {
    case one
    case two
    case three
}

struct ListView: View {
    let myEnum: StringRepresentable //doesn't work
    
    var body: some View {
        ForEach(myEnum.allCases, id: \.self) { elem in //can't access .allCases
            Text(elem.rawValue)
        }
    }
}

标签: iosswiftenumsswiftui

解决方案


您的原始代码中有几个错误。首先,您没有使用VStack(or Listor LazyVStack),因此您的 foreach 只会呈现一个元素。

其次,您将类型而不是元素本身传递给列表视图。最后,您自己的StringRepresentable协议是不必要的,您可以使用RawRepresentable它的关联类型RawValue限制为String

即是这样的:

struct ContentView: View {
    var body: some View {
        VStack {
            ListView(values: Fruits.allCases)
            ListView(values: Animals.allCases)
        }
    }
}

enum Fruits: String, CaseIterable {
    case apple
    case orange
    case banana
}

enum Animals: String, CaseIterable {
    case cat
    case dog
    case elephant
}

struct ListView<T: RawRepresentable & Hashable>: View where T.RawValue == String {
    let values: [T]

    var body: some View {
        LazyVStack {
            ForEach(values, id: \.self) { elem in
                Text(elem.rawValue)
            }
        }
    }
}

像这样呈现

使成为


推荐阅读