SwiftUI - 使用带有枚举的选择器和提供的值并返回正确的 tag()

Posted

技术标签:

【中文标题】SwiftUI - 使用带有枚举的选择器和提供的值并返回正确的 tag()【英文标题】:SwiftUI - using a picker with enum with the provided values and returning the right tag() 【发布时间】:2020-04-28 16:49:54 【问题描述】:

我有一个问题,不知道如何解决。我有几个枚举返回一个字符串,在项目中的每个地方都使用,在一个单独的 textPhrases 文件中。

我想用其中一些来填充选择器(分段)。

我试图了解我应该如何使用和设置标签元素。

我想有一个静态变量返回一个带有 [String:Int] [rawCaseValue, index] 的元组,但得到以下错误 - Type '(String, Int)' 不能符合 'Hashable' ;只有结构/枚举/类类型可以符合协议

这是我的代码示例。第二个选择器工作完美,但我想重构它以使用枚举提供的字符串。

//  TextPhrases.swift
//  Zinnig

import SwiftUI

enum SalutationClient: String, CaseIterable 
    case noChoice = "…"
    case sir = "Meneer"
    case mrs = "Mevrouw"
    case miss = "Mejuffrouw"

    static let all = SalutationClient.allCases.map  $0.rawValue 

    static var allIndexed : [(String, Int)]
    var tupleArray: [(String, Int)] = []
    var ind : Int = 0

       for salut in SalutationClient.all //allCases.map( $0.rawValue )
        
           tupleArray.append( (salut, ind))
           ind += 1
        
        return tupleArray
   



//  PersonContentView.swift
//  Zinnig


/// Main Person view
struct PersonContentView: View 

@State private var selectedSalutation = 0

/// next line will be removed and replace by an enum with Strings
@State private var dayPart: [String]  = ["…", "ochtend", "middag", "avond", "nacht"]
@State private var selectedDayPart = 0

...
Form 
        Picker(selection: $selectedSalutation, label: Text("Aanspreken met;")) 
            ForEach ( SalutationClient.allIndexed, id: \.self )  salutTuple in
                    Text((salutTuple.0)).tag((salutTuple.1))
                
        .pickerStyle(SegmentedPickerStyle())

        Picker(selection: $selectedDayPart, label: Text("Selecteer een dagdeel")) 
            ForEach(0 ..< dayPart.count) 
                 Text(self.dayPart[$0]).tag($0)
            
        .pickerStyle(SegmentedPickerStyle())
    

错误是 - 类型 '(String, Int)' 不能符合 'Hashable';只有结构/枚举/类类型可以符合协议

我应该如何着手进行这项工作?

谢谢

【问题讨论】:

【参考方案1】:

以下代码确实解决了我的问题。

//  TextPhrases.swift
//  Zinnig

enum SalutationClient: String, CaseIterable, Hashable 
    case noChoiceMade = "…"
    case sir = "Meneer"
    case mrs = "Mevrouw"
    case miss = "Mejuffrouw"

    static let all = SalutationClient.allCases.map  $0.rawValue 

    struct TupleStruct: Hashable 
        var salutation: String
        var index: Int
    

    static var allIndexed : [TupleStruct]
        var tupleArray : [TupleStruct] = []
        var ind : Int = 0

        for salut in SalutationClient.all       //allCases.map( $0.rawValue )
        
            tupleArray = tupleArray + [TupleStruct(salutation: salut, index: ind )]
            ind += 1
        
        print(tupleArray)
        return tupleArray
    


//  PersonContentView.swift
//  Zinnig

Picker(selection: $selectedSalutation, label: Text("Select een persoon type;")) 
    ForEach(SalutationClient.allIndexed, id: \.self)  salut in
        Text(salut.salutation).tag(salut.index)
    
.pickerStyle(SegmentedPickerStyle())

如果有人对此有意见,请告诉我。 我总是乐于接受更好的新事物。

【讨论】:

【参考方案2】:

你让它变得比你需要的复杂得多。 查看 Apple 的文档,该文档直接涉及您的用例。

https://developer.apple.com/documentation/swiftui/picker

【讨论】:

你是对的 - 这比 OP 自己的解决方案更简洁,但是,我认为你应该引用答案以及链接到它,因为链接会及时中断。然后OP可以将其标记为正确答案。它也更短,因为它使用了几个隐含的 Swift 技术:IdentifiableCaseIterable 以及enum StringrawValue 就是这种情况 - 你可以解释这些,Apple 网站没有,并且是 真的有用!

以上是关于SwiftUI - 使用带有枚举的选择器和提供的值并返回正确的 tag()的主要内容,如果未能解决你的问题,请参考以下文章

SwiftUI - 选择器

SwiftUI 双向绑定到枚举案例中 ObservableObject 中的值

C#中的枚举器和迭代器

由枚举驱动的 SwiftUI 选择器:值未更新

处理选项卡选择 SwiftUI

如何更改应用程序色调颜色(新的 SwiftUI 生命周期应用程序)?