如何使用绑定文本创建完全可自定义的部分?

时间:2021-06-08 12:43:30

标签: forms swiftui binding

首先,很抱歉标题根本不准确,但我不知道我还能如何命名这个问题。所以:

1.我想要达到的目标:

我想创建一个界面,用户可以在其中添加部分以输入不同的字段,这些字段可由用户自己完全自定义。

2.到目前为止我做了什么

我能够创建界面,我可以轻松添加新部分(顶部有一个“部分名称”,下面有一个 TextField),并且它们是可定制的,但仅限于 TextField。它们也是可删除的,即使我不得不做一个复杂的解决方法,因为 TextField 的绑定文本导致应用程序崩溃,因为我试图删除项目的索引结果为“超出范围”。这不是完美的解决方法,但它有效,现在这是最重要的事情。当我保存这些部分时,我会将它们保存为一个 Dictionaries 数组,其中每个 Dictionary 都有部分名称及其值。但是,仍有一些我无法做到的事情:

3.我还没有做的事情

还有 3 件事我还做不到。

首先,我希望该部分的名称是可编辑的。

其次,我希望用户添加的部分显示在表单内并按部分划分。作为标题,我希望有每个不同的部分名称,并在所有共享相同名称的相关部分内分组。

最后但并非最不重要的一点是,我希望允许用户将多个 TextField 添加到同一部分。我不知道如何处理这个问题,甚至不知道是否有可能。

4.代码:

内容视图:

import SwiftUI

struct ContentView: View {
    
    
@State var editSections = false
@State var arraySections : [SectionModel] = [SectionModel(name: "Prova", value: ""), SectionModel(name: "Prova 2", value: ""), SectionModel(name: "Prova", value: "")]
@State var showProgressView = false
@State var arraySectionsForDeleting = [SectionModel]()
@State var openSheetAdditionalSections = false


var body: some View {
    Form {
        if showProgressView == false {
            if editSections == false {
                ForEach(arraySections, id: \.id) { sect in
                    Section(header: Text(sect.name)) {
                        ForEach(arraySections, id: \.id) { sez in
                            if sez.name == sect.name {
                                SectionView(section: sez)
                            }
                        }
                    }
                }
            } else {
                forEachViewSectionsForDeleting
            }
            if arraySections.count > 0 {
                buttoneditSections
            }
            
        } else {
            loadingView
        }
        
        Section {
            addSections
        }
    }
    .sheet(isPresented: $openSheetAdditionalSections, content: {
        AdditionalSectionsSheet(closeSheet: $openSheetAdditionalSections, contView: self)
    })
}






var forEachViewSectionsForDeleting : some View {
    Section {
        ForEach(arraySections, id: \.id) { sez in
            HStack {
                Text("\(sez.name) - \(sez.value)")
                    
                    .foregroundColor(.black)
                Spacer()
                Button(action: {
                    showProgressView = true
                    let idx = arraySections.firstIndex(where: { $0.id == sez.id })
                    arraySectionsForDeleting.remove(at: idx!)
                    arraySections = []
                    arraySections = arraySectionsForDeleting
                    showProgressView = false
                }, label: {
                    Image(systemName: "minus.circle")
                        .foregroundColor(.yellow)
                }).buttonStyle(BorderlessButtonStyle())
            }
        }
    }
}
var buttoneditSections : some View {
    Button(action: {
        editSections.toggle()
    }, label: {
        Text(editSections == true ? "Done" : "Edit Sections")
            
            .foregroundColor(.yellow)
    })
}
var forEachviewSezioniNonModifica : some View {
    Section {
        ForEach(arraySections, id: \.id) { sez in
            Text(sez.name)
                
                .foregroundColor(.black)
            Text(sez.value)
                
                .foregroundColor(.black)
        }
    }
}
var addSections : some View {
    Button(action: {
        openSheetAdditionalSections = true
    }, label: {
        HStack {
            Text("Add sections")
                
                .foregroundColor(.yellow)
            Spacer()
            Image(systemName: "plus.circle")
                .foregroundColor(.yellow)
        }
    })
}
var loadingView : some View {
    Section {
        HStack {
            Spacer()
            ProgressView()
                .progressViewStyle(CircularProgressViewStyle(tint: .black))
            Spacer()
        }
    }
}

}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView()
        }
    }

AddSectionSheet 和 SectionView:

import SwiftUI

struct AdditionalSectionsSheet: View {
    
    @Binding var closeSheet : Bool
    
    @Environment(\.colorScheme) var colorScheme
    
    var contView : ContentView
    
    @Environment(\.presentationMode) var mode: Binding<PresentationMode>
    @GestureState private var dragOffset = CGSize.zero
    
    var body: some View {
        NavigationView {
            Form {
                buttonPhone
                buttonUrl
                buttonEmail
                buttonAddress
            }
            .navigationBarTitle(Text("Add section"), displayMode: .inline)
            .navigationBarBackButtonHidden(true)
            .navigationBarItems(trailing: Button(action : {
                closeSheet = false
            }){
                Text("Close")
                    
                    .foregroundColor(.yellow)
            })
        }
    }
    
    var buttonPhone : some View {
        Button(action: {
            contView.editSections = false
            
            contView.arraySections.append(SectionModel(name: "Phone", value: ""))
            
            contView.showProgressView = true
            closeSheet = false
        }, label: {
            HStack {
                Text("Phone")
                    
                    .foregroundColor(.black)
                Spacer()
            }
        })
    }
    var buttonUrl : some View {
        Button(action: {
            contView.editSections = false
            
            contView.arraySections.append(SectionModel(name: "URL", value: ""))
            
            closeSheet = false
        }, label: {
            HStack {
                Text("URL")
                    
                    .foregroundColor(.black)
                Spacer()
            }
        })
    }
    var buttonAddress : some View {
        Button(action: {
            contView.editSections = false
            
            contView.arraySections.append(SectionModel(name: "Address", value: ""))
            
            contView.showProgressView = true
            closeSheet = false
        }, label: {
            HStack {
                Text("Address")
                    
                    .foregroundColor(.black)
                Spacer()
            }
        })
    }
    var buttonEmail : some View {
        Button(action: {
            contView.editSections = false
            
            contView.arraySections.append(SectionModel(name: "Email", value: ""))
            
            contView.showProgressView = true
            closeSheet = false
        }, label: {
            HStack {
                Text("Email")
                    
                    .foregroundColor(.black)
                Spacer()
            }
        })
    }
}

struct SectionView : View {
    
    @Environment(\.colorScheme) var colorScheme
    
    @ObservedObject var section : SectionModel
    
    var body : some View {
        Section {
            Text(section.name)
                
                .foregroundColor(.black)
            
            TextField(section.name, text: self.$section.value)
                
                .foregroundColor(.black)
        }
    }
}

截面模型:

import SwiftUI
import Combine

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

    var id = UUID()
    var name : String
    var value : String
   
    init(name: String, value: String) {
    self.name = name
    self.value = value
}
    
    static func == (lhs: SectionModel, rhs: SectionModel) -> Bool {
        true
    }
    
    static func < (lhs: SectionModel, rhs: SectionModel) -> Bool {
        true
    }
}

我希望我写的东西清晰易懂,感谢所有提供帮助的人!

0 个答案:

没有答案