如何解决如何从字符串数组生成自定义文本字段,每个字符串都有自己的编辑/删除控件?
我的 IOS 应用程序有一个供用户使用的表单构建器。用户可以创建表单、向其中添加问题以及更改问题类型,包括文本响应、多项选择和复选框。对于多项选择和复选框类型,用户必须提供 2-5 个选项。
在我的 QuestionManager
(视图模型)中,我将这些选项存储为字符串数组。在视图中,我使用 OptionCell
循环生成 ForEach
。每个 OptionCell
都有一个 TextField
和控制功能,用于删除、编辑和确认每个选项。问题是我不确定我的方法,因为我认为有一些错误是由于我的设置方式造成的。
例如,这确实是唯一的问题,我在 @State var isEditing: Bool
中有一个未更新的 OptionCell
变量,我认为这与我声明 { @Published var options: [String]
中的 {1}}。或者它可能与 QuestionManager
中的 @State var option: String
有关。 (我尝试将其设置为 OptionCell
,但由于某种原因不起作用。)但是这对我来说没有任何意义,因为 @Binding
变量设置为在点击视图时更新,尽管我已将问题缩小到我最不确定的问题,并且我相信它与我上面描述的内容有某种关系。有什么建议吗?
isEditing
struct OptionCell: View {
@Observedobject var manager: QuestionManager
@State var option: String
@State var isEditing: Bool = false
var optIndex: Int
init(_ manager: QuestionManager,option: String) {
self.manager = manager
self.option = option
self.optIndex = manager.options!.firstIndex(of: option)!
}
var body: some View {
HStack {
MyCustomTextField(text: $option)
.keyboardType(.default)
.onTapGesture {
option = ""
isEditing = true // The main issue -> Isnt updating the view
}
// ActionIcon is just a Button with a SFLabels string input
ActionIcon(isEditing ? "checkmark" : "xmark",size: 10) { // No changes are recognized
isEditing ? saveOption() : deleteOption()
}
.padding(.horizontal)
}
}
func saveOption() {
if option == "" {
manager.error = "An option must not be empty"
} else {
manager.options![optIndex] = option
isEditing = false
}
}
func deleteOption() {
if manager.options!.count == 2 {
manager.error = "You must have at least two options"
} else {
manager.deleteOption(option: option)
}
}
}
struct QuestionView: View {
@Environment(\.presentationMode) var mode
@Observedobject var manager: QuestionManager
init(_ manager: QuestionManager) { self.manager = manager }
var body: some View {
ZStack {
MyCustomViewWrapper {
// ^ Reskins the background,adds padding,etc.
ScrollView {
vstack(spacing: 20) {
ConstantTitledTextField("Type",manager.type.rawValue)
// ^ Reskinned TextField
.overlay {
HStack {
Spacer()
self.changeTypeMenu
}
.padding(.horizontal)
.padding(.top,30)
}
TitledTextField("Prompt",$manager.prompt)
// ^ Another reskinned TextField
.keyboardType(.default)
.onTapGesture { manager.prompt = "" }
MyCustomDivider()
if manager.options != nil {
self.optionsSection
}
}
}
}
.alert(isPresented: $manager.error.isNotNil()) {
MyCustomAlert(manager.error!) { manager.error = nil }
}
vstack {
Spacer()
MyCustomButton("Save") { checkAndSave() }
}
.hiddenIfKeyboardActive()
}
}
var changeTypeMenu: some View {
Image(systemName: "chevron.down").icon(15)
.menuOnPress {
Button(action: { self.manager.changeType(.text) } ) { Text("Text Response") }
Button(action: { self.manager.changeType(.multiple) } ) { Text("Multiple Choice") }
Button(action: { self.manager.changeType(.checkBox) } ) { Text("CheckBox") }
}
}
var optionsSection: some View {
vstack(spacing: 15) {
HStack {
Text("Options")
.font(.title3)
.padding(.horizontal)
Spacer()
ActionIcon("plus",size: 15) { manager.addOption() }
.padding(.horizontal)
}
ForEach(manager.options!,id: \.self) { opt in
OptionCell(manager,option: opt)
}
}
}
private func checkAndSave() {
if manager.checkQuestion() {
manager.saveQuestion()
self.mode.wrappedValue.dismiss()
}
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。