Skip to content

Instantly share code, notes, and snippets.

@erd-s
Last active June 25, 2019 16:25
Show Gist options
  • Save erd-s/7351e32569754f8b7eeff91bb7dd150c to your computer and use it in GitHub Desktop.
Save erd-s/7351e32569754f8b7eeff91bb7dd150c to your computer and use it in GitHub Desktop.
ForEach Binding Issues
struct ConfigurableAddressForm : View {
@State private var formViewModel = ConfigurableFormViewModel()
var body: some View {
VStack {
if formViewModel.viewModels.isEmpty {
LoadingView().onAppear {
self.loadForms()
}
} else {
makeAddressForm(viewModel: formViewModel)
}
}
}
func makeAddressForm(viewModel: ConfigurableFormViewModel) -> some View {
Form {
Section(header: FormHeaderViewWithValidationStatus(title: viewModel.formType.capitalized, isValid: viewModel.isValid)) {
ForEach(viewModel.viewModels) { vm in
FormField(viewModel: $vm) //This is where errors occur.
}
}
Section {
makeSubmitButton(isEnabled: viewModel.isValid)
}
}
}
func loadForms() {
let fetchResult: Result<ConfigurableFormViewModel, Error> = Fetcher.fetchLocalJSON(name: "FormJSON")
switch fetchResult {
case .success(let viewModel):
self.formViewModel = viewModel
case .failure(let error):
print(error.localizedDescription)
}
}
func makeSubmitButton(isEnabled: Bool) -> some View {
HStack {
Spacer()
withAnimation {
Button(action: printAddressFromVMs, label: {
Text("Submit")
}).disabled(!isEnabled)
}
}
}
func printAddressFromVMs() {
print(formViewModel.viewModels.map { $0.output }.joined(separator: "\n"))
}
}
class ConfigurableFormViewModel: BindableObject, Codable {
var didChange = PassthroughSubject<[FormFieldViewModel], Never>()
enum CodingKeys: String, CodingKey {
case formType
case viewModels = "formFields"
}
var formType: String = "Loading..."
var viewModels: [FormFieldViewModel] = [] {
didSet {
didChange.send(viewModels)
}
}
var isValid: Bool {
return !viewModels.contains { !$0.isValid }
}
}
struct FormField : View {
@Binding var viewModel: FormFieldViewModel
var body: some View {
VStack {
TextField($viewModel.output, placeholder: Text(viewModel.placeholder))
Line(color: Color.lightGray)
}.padding()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment