SWIFTUI Call Key Dictionary not work with the error: 'Subscript index of type '() -> Bool' in a key path must be Hashable'

Viewed 643

I have this view:

import SwiftUI

struct SectionView1: View {

    let dateStr:String    
    @Binding var isSectionView:Bool

    var body: some View {
        HStack {
            Button(action: {
                self.isSectionView.toggle()
            }) {
                Image(systemName: isSectionView ? "chevron.down.circle" : "chevron.right.circle")
            }
            Text("Media del \(dateStr)")
        }
    }
}

which will be called from view:

import SwiftUI
import Photos

struct MediaView: View {
    let geoFolder:GeoFolderCD

    @State private var assetsForDate = [String :[PHAsset]]()
    @State private var isSectionViewArray:[String:Bool] = [:]

    var body: some View {
        List {
            ForEach(assetsForDate.keys.sorted(by: > ), id: \.self) { dateStr in
                Section {
                    SectionView1(dateStr: dateStr,
                                 isSectionView: self.$isSectionViewArray[dateStr, default: true])
                }
            }
        }
        .onAppear {
            self.assetsForDate = FetchMediaUtility().fetchGeoFolderAssetsForDate(geoFolder: geoFolderStruct, numAssets: numMediaToFetch)
            for dateStr in self.assetsForDate.keys.sorted() {
                self.isSectionViewArray[dateStr] = true
            }
        }
    }
}    

but I have the error: Subscript index of type '() -> Bool' in a key path must be Hashable in isSectionView: self.$isSectionViewArray[dateStr, default: true]

Why isSectionViewArray:[String:Bool] = [:] is not Hasbable?

How can modify the code for work?

If I remove, in SectionView, @Binding var isSectionView:Bool, the code work fine, or if I set, from SectionView, @Binding var isSectionViewArray:[String:Bool] = [:], the code work fine.

1 Answers

You can write your own binding with the below code and it should work

var body: some View {
        List {
            ForEach(assetsForDate.keys.sorted(by: > ), id: \.self) { dateStr in
                let value = Binding<Bool>(get: { () -> Bool in
                    return self.isSectionViewArray[dateStr, default: true]
                }) { (value) in

                }
                Section {
                    SectionView1(dateStr: dateStr,
                                 isSectionView: value)
                }
            }
        }
        .onAppear {
            self.assetsForDate = FetchMediaUtility().fetchGeoFolderAssetsForDate(geoFolder: geoFolderStruct, numAssets: numMediaToFetch)
            for dateStr in self.assetsForDate.keys.sorted() {
                self.isSectionViewArray[dateStr] = true
            }
        }
    }
Related