如何使用SwiftUI动态添加文本字段如联系人?

问题描述

我有一个表格,希望用户添加任意​​数量的促销代码。最接近的本机示例是在“联系人”应用程序中。请参阅add url部分,该部分不需要“主页”或“主页”链接,但删除功能为:

enter image description here

如何用SwiftUI构造它,还是有推荐使用的解决方案?感谢您的帮助!

解决方法

所以这是非常快速和肮脏的,但是它应该使您对进入的方向有所了解:

struct PromoCodeView: View {
    
    @State var codes = [String]()
    
    func getBinding(forIndex index: Int) -> Binding<String> {
        return Binding<String>(get: { codes[index] },set: { codes[index] = $0 })
    }
    
    var body: some View {
        NavigationView {
            Form {
                Section(header: Text("Promo Codes")) {
                    ForEach(0..<codes.count,id: \.self) { index in
                        HStack {
                            Button(action: { codes.remove(at: index) }) {
                                Image(systemName: "minus.circle.fill")
                                    .foregroundColor(.red)
                                    .padding(.horizontal)
                            }
                            TextField("Promo Code",text: getBinding(forIndex: index))
                        }
                    }
                    Button(action: { codes.append("") }) {
                        HStack {
                            Image(systemName: "plus.circle.fill")
                                .foregroundColor(.green)
                                .padding(.horizontal)
                            Text("add promo code")
                        }
                    }
                }
            }
            .navigationBarTitle("Codes")
        }
    }
}

看起来像这样:

enter image description here

编辑:


好的,所以我使它更加通用,因此您可以放下视图并为其绑定到字符串数组:

struct ListEditor: View {
    
    var title: String
    var placeholderText: String
    var addText: String
    @Binding var list: [String]
    
    func getBinding(forIndex index: Int) -> Binding<String> {
        return Binding<String>(get: { list[index] },set: { list[index] = $0 })
    }
    
    
    var body: some View {
        Section(header: Text(title)) {
            ForEach(0..<list.count,id: \.self) { index in
                ListItem(placeholder: placeholderText,text: getBinding(forIndex: index)) { self.list.remove(at: index) }
            }
            AddButton(text: addText) { self.list.append("") }
        }
    }
}

fileprivate struct ListItem: View {
    
    var placeholder: String
    @Binding var text: String
    var removeAction: () -> Void
    
    var body: some View {
        HStack {
            Button(action: removeAction) {
                Image(systemName: "minus.circle.fill")
                    .foregroundColor(.red)
                    .padding(.horizontal)
            }
            TextField(placeholder,text: $text)
        }
    }
    
}

fileprivate struct AddButton: View {
    
    var text: String
    var addAction: () -> Void
    
    var body: some View {
        Button(action: addAction) {
            HStack {
                Image(systemName: "plus.circle.fill")
                    .foregroundColor(.green)
                    .padding(.horizontal)
                Text(text)
            }
        }
    }
}


fileprivate struct TestButton: View {

    var label: String
    var action: () -> Void


    var body: some View {
        Button(action: action) {
            Text(self.label)
                .foregroundColor(.white)
            .frame(width: 300,height: 75)
        }
        .background(Color.blue)
        .cornerRadius(10)
        .padding()
    }

}

您可以像这样使用它:

struct TestView: View {
    
    @State var codes = [String]()
    
    var body: some View {
        NavigationView {
            Form {
                ListEditor(title: "Promo Codes",placeholderText: "Promo Code",addText: "add promo code",list: $codes)
            }
            .navigationBarTitle("Codes")
        }
    }
    
}

它看起来与上面的GIF相同。