微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何从字符串数组生成自定义文本字段,每个字符串都有自己的编辑/删除控件?

如何解决如何从字符串数组生成自定义文本字段,每个字符串都有自己的编辑/删除控件?

我的 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] 举报,一经查实,本站将立刻删除。