SwiftUI-为不同的选择器使用枚举的所有值,但不使用一个值

SwiftUI-为不同的选择器使用枚举的所有值,但不使用一个值,swift,enums,swiftui,picker,Swift,Enums,Swiftui,Picker,在我的应用程序中,我需要在两个不同的位置使用选择器。在一个地方,将属性设置为三个值中的一个:a、B或C。但是,在另一个地方,我想使用选择器过滤项目数组,以显示所有项目(无过滤器)或仅显示a、B或C项目 因此,我的第一次尝试是创建一个enum,如下所示: enum Category { case all case A case B case C } 使用此选项,我可以成功筛选我的列表。但是,当我尝试在数组中创建新项时,我不希望all成为一个选项。用户应该只看到带有a、B和C的选择

在我的应用程序中,我需要在两个不同的位置使用
选择器。在一个地方,将属性设置为三个值中的一个:a、B或C。但是,在另一个地方,我想使用选择器过滤项目数组,以显示所有项目(无过滤器)或仅显示a、B或C项目

因此,我的第一次尝试是创建一个
enum
,如下所示:

enum Category {
  case all
  case A
  case B
  case C
}
使用此选项,我可以成功筛选我的列表。但是,当我尝试在数组中创建新项时,我不希望
all
成为一个选项。用户应该只看到带有a、B和C的选择器

我可以试试:

enum Category {
  case A
  case B
  case C
}
但是如何为过滤器选择器添加
all
选项呢

(为了回应下面的一些评论,这里有一些关于我试图完成的具体事情的更多细节

锦标赛可以是男子、女子或混合锦标赛。在我列出锦标赛的屏幕上,我希望能够显示所有锦标赛,或仅显示男子、女子或混合锦标赛。因此,我有一个横跨iPhone宽度的选择器。外观和工作都很棒

显然,在向列表中添加新项目时,我必须指定其类别,但不能指定“全部”。还必须指定选择器


因此,在一种情况下,我需要三个值,在另一种情况下,我需要相同的三个值,并在开始处添加“All”。

您可以使枚举
CaseIterable
可编辑,然后当您要显示所有枚举值时,可以使用
allCases
属性,当您只想显示某些案例时,请使用
过滤器

注意:在我的示例代码中,您需要将
选项:.constant(Category.a)
替换为
@Binding

struct Test {
    enum Category: String, CaseIterable {
        case all = "All"
        case a = "A"
        case b = "B"
        case c = "C"
    }
    
    struct TestView: View {
        var body: some View {
            VStack {
                Picker("Picker Title", selection: .constant(Category.a)) {
                    ForEach(Category.allCases, id: \.self) { category in
                        Text(category.rawValue).tag(category)
                    }
                }
                
                Picker("Picker Title", selection: .constant(Category.a)) {
                    ForEach(Category.allCases.filter({ $0 != .all }), id: \.self) { category in
                        Text(category.rawValue).tag(category)
                    }
                }
            }
        }
    }
}

您可以使枚举
CaseIterable
,然后当您想要显示所有枚举值时,可以使用
allCases
属性,当您只想显示某些案例时,可以使用
过滤器

注意:在我的示例代码中,您需要将
选项:.constant(Category.a)
替换为
@Binding

struct Test {
    enum Category: String, CaseIterable {
        case all = "All"
        case a = "A"
        case b = "B"
        case c = "C"
    }
    
    struct TestView: View {
        var body: some View {
            VStack {
                Picker("Picker Title", selection: .constant(Category.a)) {
                    ForEach(Category.allCases, id: \.self) { category in
                        Text(category.rawValue).tag(category)
                    }
                }
                
                Picker("Picker Title", selection: .constant(Category.a)) {
                    ForEach(Category.allCases.filter({ $0 != .all }), id: \.self) { category in
                        Text(category.rawValue).tag(category)
                    }
                }
            }
        }
    }
}

可以用这种方法创建枚举

enum Category {
    case all
    case A
    case B
    case C
    
    static let categories: [Category] = [.A, .B, .C]
}

然后在需要从三个类别中进行选择时使用categories数组。

您可以用这种方式创建枚举

enum Category {
    case all
    case A
    case B
    case C
    
    static let categories: [Category] = [.A, .B, .C]
}

然后在需要从三个类别中进行选择时使用categories数组。

您应该定义
enum
而不使用
all
大小写,因为
all
不是项目的有效
类别。(这是一个称为“.”的编程指南)

根据该定义,用于设置项目属性的
选择器可以如下所示:

Picker("Category", selection: $category) {
    ForEach(Category.allCases, id: \.self) { category in
        Text(verbatim: "\(category)")
            .tag(category)
    }
}
然后您应该认识到您的过滤器是可选的。您可以按项目类别筛选,也可以不执行筛选。因此,您的筛选器属性应声明为可选:

@Binding var categoryFilter: Category?
用于设置过滤器的
选择器
需要小心使用可选标签:

Picker("Category Filter", selection: $categoryFilter) {
    Text("None")
        .tag(Category?.none)
    ForEach(Category.allCases, id: \.self) { category in
        Text(verbatim: "\(category)")
            .tag(Category?.some(category))
    }
}

您应该定义
enum
,而不使用
all
大小写,因为
all
不是项目的有效
Category
。(这是一个称为“.”的编程指南)

根据该定义,用于设置项目属性的
选择器可以如下所示:

Picker("Category", selection: $category) {
    ForEach(Category.allCases, id: \.self) { category in
        Text(verbatim: "\(category)")
            .tag(category)
    }
}
然后您应该认识到您的过滤器是可选的。您可以按项目类别筛选,也可以不执行筛选。因此,您的筛选器属性应声明为可选:

@Binding var categoryFilter: Category?
用于设置过滤器的
选择器
需要小心使用可选标签:

Picker("Category Filter", selection: $categoryFilter) {
    Text("None")
        .tag(Category?.none)
    ForEach(Category.allCases, id: \.self) { category in
        Text(verbatim: "\(category)")
            .tag(Category?.some(category))
    }
}

如果我理解正确,我会回答你的问题

  • 修改枚举以实现CaseIterable,请看下面的内容

     enum Category:CaseIterable{
      case all
      case A
      case B   
      case C
     }
    
  • 筛选出您的类别与所有案例匹配的位置。下面的例子

    let preferredcategory = Category.allCases.filter{ return $0 !=  Category.all}
    
  • 要测试我们的结果,请参阅下面的代码

     print(preferredcategory.count)
     for catname in preferredcategory {
     print("Hello, \(catname)!")
    }
    
  • 您可以在相应的页面上阅读更多内容

  • 谢谢

    因此,您可以使用preferredCategory变量向用户显示您不希望所有人都显示的类别。您还可以使用相同的筛选器仅显示包含所有大小写的枚举部分

    另外,好处是您可以保留枚举,并在应用程序中的任何地方重用它,而无需硬编码值。如果只想显示所有内容,只需过滤掉剩余的案例即可


    有些人可能想在没有正当理由的情况下否决投票,但如果你认为这种方法是错误的,请随意编辑或就如何改进解决方案发表评论。

    如果我理解正确,请回答你的问题

  • 修改枚举以实现CaseIterable,请看下面的内容

     enum Category:CaseIterable{
      case all
      case A
      case B   
      case C
     }
    
  • 筛选出您的类别与所有案例匹配的位置。下面的例子

    let preferredcategory = Category.allCases.filter{ return $0 !=  Category.all}
    
  • 要测试我们的结果,请参阅下面的代码

     print(preferredcategory.count)
     for catname in preferredcategory {
     print("Hello, \(catname)!")
    }
    
  • 您可以在相应的页面上阅读更多内容

  • 谢谢

    因此,您可以使用preferredCategory变量向用户显示您不希望所有人都显示的类别。您还可以使用相同的筛选器仅显示包含所有大小写的枚举部分

    另外,好处是您可以保留枚举,并在应用程序中的任何地方重用它,而无需硬编码值。如果只想显示所有内容,只需过滤掉剩余的案例即可


    有些人可能想在没有正当理由的情况下否决投票,但如果您认为该方法是错误的,请随意编辑或留下有关如何改进解决方案的评论。

    是否最好将“全部”排除在枚举之外,然后ForEach over[“全部”]+Category.allCases,不是通过读取原始post
    ,而是如何为筛选器选择器添加all选项,而是需要显示“all”。就个人而言,从UI的角度来看,这可能不是允许用户选择这些“类别”的最佳方式。也许是一个可用类别的列表(