SwiftUI - 如何创建一个从 属性 中选择值的选取器?

SwiftUI - How do I create a Picker that selects values from a property?

我有这两个模型,第一个:

import SwiftUI
import Combine

class FolderModel : Codable, Identifiable, Equatable, ObservableObject  {

    var id = UUID()
    var folderName : String
    var values : [ValueModel] = []
    
    init(folderName: String) {
        self.folderName = folderName
    }
}

第二个:

import SwiftUI
import Combine

class ValueModel : Codable, Identifiable, Equatable, ObservableObject, Comparable {

    var id = UUID()
    var name : String
    var notes : String?
    var expires : Date?
    
    init(name: String, notes: String?, expires: Date?) {
        self.name = name
        self.notes = notes
        self.expires = expires
    }
}

以及这些存储空间:

import SwiftUI
import Combine

class DataManager : Equatable, Identifiable, ObservableObject {


static let shared = DataManager()

@Published var storageValues : [ValueModel] = []
typealias StorageValues = [ValueModel]


@Published var storageFolder : [FolderModel] = []
typealias StorageFolder = [FolderModel]

//The rest of the code
}

然后我有一个值的详细视图,其中显示了他的所有属性。从那里,我想 select 用户想要放入的文件夹(在代码中转换为将该值附加到 FolderModel 的数组“值”中)。 为此,我尝试创建一个显示所有文件夹(按名称)并且可以 selected 的选择器,这样当我按“保存”时,我可以执行类似“selectedFolder.append”的操作(价值)”。我尝试创建的选择器是这样的:

import SwiftUI
struct DetailValueView: View {

@ObservedObject var dm : DataManager
@State private var selector = 0
@State var selectedFolder : FolderModel?

    var body: some View {
        Form {
            Section(header: Text("Properties")) {
                folderCell
                if hasFolder == true {
                picker
                }
            }
        }
    }

var folderCell : some View {
    VStack {
        Toggle(isOn: $hasFolder) {
            if hasFolder == true {
                VStack(alignment: .leading) {
                    Text("Folder: " + "//Here I would like to display the selected value")
                }
            } else if hasFolder == false {
                Text("Folder")
            }
        }
   }
}

var picker : some View {
    Picker(selection: $selector, label: Text("Select Folder")) {
        ForEach(dm.storageFolder) { foldersForEach in
              Button(action: {
                  selectedFolder = foldersForEach
              }, label: {
                  Text(foldersForEach.folderName)
              })
        }
    }.pickerStyle(DefaultPickerStyle())
}

我试图在网上找到解决方案,但我并不真正了解 Picker 的工作原理,我不明白如何使用“@State private var selector = 0”来获取我想要的价值。 感谢所有帮助我的人!

这里要强调两点:首先,您需要将表单包装在 NavigationView 中或将选择器样式更改为 WheelPickerStyle。否则选择器将无法工作(请参阅 here 了解详细说明)。其次,您的状态 selector 是整数类型。因此,请确保也循环遍历整数。现在您的状态 selector 包含从文件夹列表中选择的文件夹的索引。

请看下面我的工作示例:

struct ContentView: View {
    @ObservedObject var dm: DataManager
    @State private var selector = 0
    @State private var hasFolder = false

    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Properties")) {
                    folderCell
                    if !dm.storageFolder.isEmpty {
                    picker
                    }
                }
            }
        }
    }

    var folderCell : some View {
        VStack {
            Toggle(isOn: $hasFolder) {
                if hasFolder == true {
                    VStack(alignment: .leading) {
                        Text("Folder: \(dm.storageFolder[selector].folderName)")
                    }
                } else if hasFolder == false {
                    Text("Folder")
                }
            }
       }
    }

    var picker : some View {
        Picker(selection: $selector, label: Text("Select Folder")) {
            ForEach(0 ..< dm.storageFolder.count) {
                Text(dm.storageFolder[[=10=]].folderName)
            }
        }.pickerStyle(DefaultPickerStyle())
    }
}