SwiftUI - 在按钮单击时添加一行多个 Textfields/Views
SwiftUI - Add a row of multiple Textfields/Views on button click
我正在使用 SwiftUI
构建一个功能,用户可以点击一个按钮来创建行,每行都有多个视图(文本字段、单选按钮...)[见下图]
我创建了一个 swift class DynamicSkills
来处理项目的创建和“添加”按钮,但是当我单击“添加”时应用程序完全崩溃,下面是我的代码far 和一张显示它应该如何的图像,我刚开始使用 SwiftUI 并且我没有完全掌握 Binding<>
.
的概念
我应该怎么做才能让它起来运行?
//DynamicSkills.swift
struct SkillListEditor: View {
@Binding var evalList: [String]
@Binding var skillList: [String]
func getBindingS(forIndex index: Int) -> Binding<String> {
return Binding<String>(get: { skillList[index] },
set: { skillList[index] = [=11=] })
}
func getBindingE(forIndex index: Int) -> Binding<String> {
return Binding<String>(get: { evalList[index] },
set: { evalList[index] = [=11=] })
}
var body: some View {
ForEach(0..<skillList.count, id: \.self) { index in
ListItem(skillEvaluation: getBindingE(forIndex: index), text: getBindingS(forIndex: index)) { self.skillList.remove(at: index) }
}
AddButton{ self.skillList.append("") }
}
}
fileprivate struct ListItem: View {
@Binding var skillEvaluation: String
@Binding var text: String
var removeAction: () -> Void
var body: some View {
VStack(alignment: .leading){
Spacer().frame(height: 8)
HStack{
Button(action: removeAction) {
Image(systemName: "minus.circle.fill")
.foregroundColor(.red)
.padding(.horizontal)
}
TextField("Skill", text: $text)
.padding(.all)
.background(Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0))
.cornerRadius(6)
}
HStack{
Text("Evaluation").font(.callout)
Spacer()
}
HStack{
RadioButtonField(id: "1", label: "1", isMarked: $skillEvaluation.wrappedValue == "1" ? true : false) { selected in
self.skillEvaluation = selected
}
Spacer()
RadioButtonField(id: "2", label: "2", isMarked: $skillEvaluation.wrappedValue == "2" ? true : false) { selected in
self.skillEvaluation = selected
}
Spacer()
RadioButtonField(id: "3", label: "3", isMarked: $skillEvaluation.wrappedValue == "3" ? true : false) { selected in
self.skillEvaluation = selected
}
Spacer()
RadioButtonField(id: "4", label: "4", isMarked: $skillEvaluation.wrappedValue == "4" ? true : false) { selected in
self.skillEvaluation = selected
}
Spacer()
RadioButtonField(id: "5", label: "5", isMarked: $skillEvaluation.wrappedValue == "5" ? true : false) { selected in
self.skillEvaluation = selected
}
}
}
}
}
fileprivate struct AddButton: View {
var addAction: () -> Void
var body: some View {
HStack{
Spacer()
Button(action: addAction) {
Text("add skill").padding(.horizontal, 12).padding(.vertical, 6).background(.white).foregroundColor(Color("PassioGreen")).overlay(RoundedRectangle(cornerRadius: 25).stroke(Color("PassioGreen"), lineWidth: 2))
}
}.padding(.top, 14)
}
}
在 ContentView
的主屏幕中,我是这样显示的:
//ContentView.swift
@State var skills = [String]()
@State var skillsEvals = [String]()
struct ContentView: View {
NavigationView{
VStack{
HStack{
Text("Skills").font(.headline)
Spacer()
}
HStack{
Text("Add up to 5 skills").font(.callout)
Spacer()
}
SkillListEditor(evalList: $skillsEvals, skillList: $skills)
}
}
}
更新:这是自定义单选按钮class CustomRadio.swift
//Custom Radio button used:
struct RadioButtonField: View {
let id: String
let label: String
let isMarked: Bool
let callback: (String)->()
init(
id: String,
label:String,
isMarked: Bool = false,
callback: @escaping (String)->()
) {
self.id = id
self.label = label
self.isMarked = isMarked
self.callback = callback
}
var body: some View {
Button(action:{
self.callback(self.id)
}) {
VStack(alignment: .center) {
Text(label).foregroundColor(self.isMarked ? .white : .black).bold().padding(.horizontal, 8).padding(.vertical, 8)
}
}
.padding()
.background(self.isMarked ? Color("PassioGreen") : Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0))
.cornerRadius(10)
}
}
您的 AddButton
操作将一个项目附加到 skillList
,但没有将一个项目附加到 evalList
。因此,当 ListItem
使用其 skillEvaluation
绑定时,绑定的 getter 会尝试访问 evalList
中不存在的元素。
试试这个:
AddButton {
self.evalList.append("")
self.skillList.append("")
}
我正在使用 SwiftUI
构建一个功能,用户可以点击一个按钮来创建行,每行都有多个视图(文本字段、单选按钮...)[见下图]
我创建了一个 swift class DynamicSkills
来处理项目的创建和“添加”按钮,但是当我单击“添加”时应用程序完全崩溃,下面是我的代码far 和一张显示它应该如何的图像,我刚开始使用 SwiftUI 并且我没有完全掌握 Binding<>
.
我应该怎么做才能让它起来运行?
//DynamicSkills.swift
struct SkillListEditor: View {
@Binding var evalList: [String]
@Binding var skillList: [String]
func getBindingS(forIndex index: Int) -> Binding<String> {
return Binding<String>(get: { skillList[index] },
set: { skillList[index] = [=11=] })
}
func getBindingE(forIndex index: Int) -> Binding<String> {
return Binding<String>(get: { evalList[index] },
set: { evalList[index] = [=11=] })
}
var body: some View {
ForEach(0..<skillList.count, id: \.self) { index in
ListItem(skillEvaluation: getBindingE(forIndex: index), text: getBindingS(forIndex: index)) { self.skillList.remove(at: index) }
}
AddButton{ self.skillList.append("") }
}
}
fileprivate struct ListItem: View {
@Binding var skillEvaluation: String
@Binding var text: String
var removeAction: () -> Void
var body: some View {
VStack(alignment: .leading){
Spacer().frame(height: 8)
HStack{
Button(action: removeAction) {
Image(systemName: "minus.circle.fill")
.foregroundColor(.red)
.padding(.horizontal)
}
TextField("Skill", text: $text)
.padding(.all)
.background(Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0))
.cornerRadius(6)
}
HStack{
Text("Evaluation").font(.callout)
Spacer()
}
HStack{
RadioButtonField(id: "1", label: "1", isMarked: $skillEvaluation.wrappedValue == "1" ? true : false) { selected in
self.skillEvaluation = selected
}
Spacer()
RadioButtonField(id: "2", label: "2", isMarked: $skillEvaluation.wrappedValue == "2" ? true : false) { selected in
self.skillEvaluation = selected
}
Spacer()
RadioButtonField(id: "3", label: "3", isMarked: $skillEvaluation.wrappedValue == "3" ? true : false) { selected in
self.skillEvaluation = selected
}
Spacer()
RadioButtonField(id: "4", label: "4", isMarked: $skillEvaluation.wrappedValue == "4" ? true : false) { selected in
self.skillEvaluation = selected
}
Spacer()
RadioButtonField(id: "5", label: "5", isMarked: $skillEvaluation.wrappedValue == "5" ? true : false) { selected in
self.skillEvaluation = selected
}
}
}
}
}
fileprivate struct AddButton: View {
var addAction: () -> Void
var body: some View {
HStack{
Spacer()
Button(action: addAction) {
Text("add skill").padding(.horizontal, 12).padding(.vertical, 6).background(.white).foregroundColor(Color("PassioGreen")).overlay(RoundedRectangle(cornerRadius: 25).stroke(Color("PassioGreen"), lineWidth: 2))
}
}.padding(.top, 14)
}
}
在 ContentView
的主屏幕中,我是这样显示的:
//ContentView.swift
@State var skills = [String]()
@State var skillsEvals = [String]()
struct ContentView: View {
NavigationView{
VStack{
HStack{
Text("Skills").font(.headline)
Spacer()
}
HStack{
Text("Add up to 5 skills").font(.callout)
Spacer()
}
SkillListEditor(evalList: $skillsEvals, skillList: $skills)
}
}
}
更新:这是自定义单选按钮class CustomRadio.swift
//Custom Radio button used:
struct RadioButtonField: View {
let id: String
let label: String
let isMarked: Bool
let callback: (String)->()
init(
id: String,
label:String,
isMarked: Bool = false,
callback: @escaping (String)->()
) {
self.id = id
self.label = label
self.isMarked = isMarked
self.callback = callback
}
var body: some View {
Button(action:{
self.callback(self.id)
}) {
VStack(alignment: .center) {
Text(label).foregroundColor(self.isMarked ? .white : .black).bold().padding(.horizontal, 8).padding(.vertical, 8)
}
}
.padding()
.background(self.isMarked ? Color("PassioGreen") : Color(red: 239.0/255.0, green: 243.0/255.0, blue: 244.0/255.0, opacity: 1.0))
.cornerRadius(10)
}
}
您的 AddButton
操作将一个项目附加到 skillList
,但没有将一个项目附加到 evalList
。因此,当 ListItem
使用其 skillEvaluation
绑定时,绑定的 getter 会尝试访问 evalList
中不存在的元素。
试试这个:
AddButton {
self.evalList.append("")
self.skillList.append("")
}