首页 > 解决方案 > How to create a set of two types in swift?

问题描述

I am new to Swift and SwiftUI. I have two structs:

struct SongModel: Identifiable, Hashable {
    let id: Int
    var path: String
    var artist: String
    var title: String
    var genre: String
    var sample_rate: Int
    var bitrate: Int
    var duration: Int
    var cover: String
    var remaining: Int?
    var created_at: String
    var filename: String
    var file_size: Int64
}

And second one:

struct FolderModel: Identifiable, Hashable {
    let id: Int
    var parent_id: Int?
    var name: String
    var files_quantity: Int
    var duration: Int
    var folder_size: Int64
    var created_at: String
    var files: [SongModel] = []
}

Also I have a list to present arrays of given models:

List(selection: self.$selectKeeper) {
                    ForEach(self.filemanager.folders, id: \.self) { folder in
                        FolderItemView(folder: folder)
                            .environmentObject(self.filemanager.appSettings)
                            .listRowBackground(Color.white)
                            .onTapGesture(count: 2) {
                                withAnimation {
                                    self.filemanager.openFolder(folder: folder)
                                }
                            }
                    }.onDelete(perform: self.onDelete)
                    ForEach(self.filemanager.files, id: \.self) { file in
                        FileItemView(file: file)
                            .environmentObject(self.filemanager.appSettings)
                            .listRowBackground(Color.white)
                    }.onDelete(perform: self.onDelete)
                }
                .environment(\.editMode, .constant(.active))

I want to make selection of these objects, so I`ve create a selectKeeper property. I can select only folders/files with

@State var selectKeeper = Set<SongModel>()

or

@State var selectKeeper = Set<FolderModel>()

But when I try

@State var selectKeeper = Set<AnyHashable>()

Code compiles successfully but selection doesn't work. I can set a checkmark but after some seconds it gone away and my selectKeeper variable is empty. How can I make set of SongModel and FolderModel?

标签: swiftlistsetswiftui

解决方案


Your approach almost worked. I used Set aswell. You just need one ForEach inside your List so it will work.

struct ContentView: View {
    @State var selectKeeper : Set<AnyHashable>? = Set<AnyHashable>()
            
    var set : Set<AnyHashable>
    
    init()
    {
        self.set = Set<AnyHashable>()
        
        self.set.insert(SongModel(id: 23, path: "Test", artist: "Test", title: "Test", genre: "Test", sample_rate: 123, bitrate: 123, duration: 123, cover: "Test", remaining: 123, created_at: "Test", filename: "Test", file_size: 123))
        
        self.set.insert(FolderModel(id: 1232, name: "Test", files_quantity: 2, duration: 2, folder_size: 23, created_at: "2020"))
    }

    var body: some View {
        List(selection: $selectKeeper) {
            ForEach(Array(self.set), id: \.self) { item in
                HStack
                {
                    if (item is SongModel)
                    {
                        //Item is SongModel
                        Text(String((item as! SongModel).id))
                    }
                    else
                    {
                        //Item is FolderModel, better to check object type again  here
                    }
                }
            }
        }
    }
}

I am creating a sample Set in the init method with two different objects. They will be added to the Set. You just use one ForEach and then check inside whether it is a object of class SongModel or FolderModel.


推荐阅读