SwiftUI 动态创建枚举或

SwiftUI Dynamically Create Enum or

我有一个自定义选择器,其中选择器的内容是根据下载的 JSON 文件创建的。为了为有挑战的用户提供更好的可访问性,我尝试使用 .accessibilityFocused 修饰符将 VO 集中在用户之前的选择上。这意味着当用户第一次查看选择器时,它应该从顶部开始,但如果他们返回更改他们的选择,它应该自动关注他们之前的选择,而不是让他们从列表顶部重新开始。

问题是要使用 .accessibilityFocused,您确实需要通过枚举来执行此操作,这样您就可以调用类似 .accessibilityFocused($pickerAccessFocus, equals: .enumValue) 的方法。当我使用 ForEach 循环基于解析 JSON 然后存储在结构中时创建的数组创建选择器时,我还没有弄清楚如何基于关闭创建各种枚举案例那个数组的。

所以,回顾一下:

  1. 在 ForEach 循环中,我需要一个 .accessibilityFocused 修饰符来标识每个选择器选项

  2. onAppear 需要按照...

    if salutation == salutation.salutation {
        DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
            pickerAccessFocus = .ENUMCASE
        }
    } else {
        pickerAccessFocus = Optional.none
    }

虽然显然 onAppear 不喜欢有 ForEach 语句,所以我也不确定如何解决这个问题。

我知道我提供的示例中有很多代码,但我试图将它们全部组合成尽可能简单的示例。希望它有意义。

如果我的想法是错误的,并且有更好的解决方案,我洗耳恭听。

import SwiftUI

struct Picker: View {

    @AccessibilityFocusState var pickerAccessFocus: PickerAccessFocus?
    @State private var salutation = ""
    var salutationList: [SalutationOptions] = [] // SalutationOptions is the struct from the parsed JSON

    enum PickerAccessFocus: Hashable {
        case ? // These cases need to be dynamically created as the same values the ForEach loop uses
    }

    static func nameSalutationPicker(name: String) -> LocalizedStringKey { LocalizedStringKey(String("NAME_SALUTATION_PICKER_\(name)")) }

    var body: some View {

        List {
            Section {
                ForEach(salutationList, id: \.id) { salutation in

                    HStack {
                        Text(nameSalutationPicker(name: salutation.salutation))

                    } // End HStack
                    .contentShape(Rectangle())
                    .accessibilityFocused(salutation == salutation.salutation ? ($pickerAccessFocus, equals: .ENUMCASE) : ($pickerAccessFocus, equals: Optional.none))
                } // End ForEach

            } // End Section

        } // End List

        .onAppear {
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.2) {
                pickerAccessFocus = .ENUMCASE
            }
        }
    }
}

你把它弄得比必要的复杂得多。您不需要 enum,您可以使用任何值,甚至直接使用您的数组值。

struct ContentView: View {
    
    @AccessibilityFocusState var pickerAccessFocus: SalutationOptions?
    @State private var salutation = ""
    var salutationList: [SalutationOptions] = []
    
    var body: some View {
        
        List {
            Section {
                ForEach(salutationList, id: \.id) { salutation in
                    
                    HStack {
                        Text(salutation.salutation)
                        
                    } // End HStack
                    .contentShape(Rectangle())
                    .accessibilityFocused($pickerAccessFocus, equals: salutation)
                } // End ForEach
                
            } // End Section
            
        } // End List
    }
}