swift - 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?
解决方案
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
.
推荐阅读
- javascript - 表单提交被取消,因为当我尝试隐藏模式 Jquery 时表单未连接
- python - 不影响 numpy mean 性能的 MKL 线程数
- python - 如何以非常简单的方式获取从用户输入中输入的变量的值?
- python - 如何显示密码测试仪输入的所有错误
- javafx - fontawesomefx 未在 Gluon SceneBuilder 10 中完全加载
- android - onclick 时将数据从 ListView 传递到活动
- powershell - 在 Powershell 中返回一个可选列表
- ruby-on-rails - Rails minitest 返回“NoMethodError: undefined method `make_response!'”
- java - Java Instant.parse on Date java 8
- javascript - 回显 UTC 时间