Created
August 1, 2023 06:51
-
-
Save damodarnamala/088cabb5d49d72cc467c79ae3bc05f50 to your computer and use it in GitHub Desktop.
Adding DynamicForms
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// ViewController.swift | |
// FormConfig | |
// | |
// Created by Damodar Namala on 01/08/23. | |
// | |
import UIKit | |
class ViewController: UIViewController { | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
// Do any additional setup after loading the view. | |
} | |
@IBAction func next() { | |
let vc = FormView.buildForm() | |
self.present(vc, animated: true) | |
} | |
} | |
class FormViewModel { | |
var configuration: FormView.Configuration | |
init(configuration: FormView.Configuration) { | |
self.configuration = configuration | |
} | |
} | |
class FormViewController: UIViewController { | |
var continer: UIStackView = { | |
let stack = UIStackView(frame: .zero) | |
stack.axis = .vertical | |
stack.alignment = .leading | |
stack.translatesAutoresizingMaskIntoConstraints = false | |
return stack | |
}() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
self.view.backgroundColor = .lightGray.withAlphaComponent(0.15) | |
self.view.addSubview(continer) | |
NSLayoutConstraint.activate([ | |
self.continer.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16), | |
self.continer.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16), | |
self.continer.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 16), | |
self.continer.bottomAnchor.constraint(lessThanOrEqualTo: self.view.bottomAnchor, constant: -16), | |
]) | |
self.viewModel.configuration.steps.lazy.forEach { step in | |
switch step { | |
case .from(let controller): | |
self.addChildViewController(child: controller) | |
case .to(let controller): | |
self.addChildViewController(child: controller) | |
case .amount(let controller): | |
self.addChildViewController(child: controller) | |
} | |
} | |
} | |
func addChildViewController(child: UIViewController) { | |
child.willMove(toParent: self) | |
self.addChild(child) | |
continer.addArrangedSubview(child.view) | |
child.willMove(toParent: self) | |
} | |
var viewModel: FormViewModel | |
init(viewModel: FormViewModel) { | |
self.viewModel = viewModel | |
super.init(nibName: nil, bundle: nil) | |
} | |
@available(*, unavailable) | |
required init?(coder: NSCoder) { | |
fatalError("\(#function) has not been implemented") | |
} | |
} | |
struct FormView { | |
private init() {} | |
static func buildForm() -> UIViewController { | |
let viewModel = FormViewModel(configuration: .init(steps: [ | |
.amount(FormView.buildAmountController()), | |
.from(FormView.buildFromAccountController()), | |
.to(FormView.buildToAccountController()), | |
])) | |
return FormViewController(viewModel: viewModel) | |
} | |
static func buildFromAccountController() -> UIViewController { | |
FromViewController() | |
} | |
static func buildToAccountController() -> UIViewController { | |
ToViewController() | |
} | |
static func buildAmountController() -> UIViewController { | |
AmountViewController() | |
} | |
} | |
extension FormView { | |
struct Configuration { | |
var steps: [FormField] = [ | |
.from(FormView.buildFromAccountController()), | |
.to(FormView.buildToAccountController()), | |
.amount(FormView.buildAmountController()) | |
] | |
} | |
} | |
public enum FormField { | |
case from(UIViewController) | |
case to(UIViewController) | |
case amount(UIViewController) | |
} | |
class FromViewController: UIViewController { | |
var label: UILabel = { | |
let view = UILabel(frame: .zero) | |
view.font = .preferredFont(forTextStyle: .largeTitle) | |
view.textColor = .red | |
view.translatesAutoresizingMaskIntoConstraints = false | |
view.text = "FromView" | |
view.textAlignment = .center | |
return view | |
}() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
self.view.backgroundColor = .lightGray.withAlphaComponent(0.15) | |
self.view.addSubview(label) | |
NSLayoutConstraint.activate([ | |
self.label.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16), | |
self.label.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16), | |
self.label.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 16), | |
self.label.bottomAnchor.constraint(lessThanOrEqualTo: self.view.bottomAnchor, constant: -16), | |
]) | |
} | |
init() { | |
super.init(nibName: nil, bundle: nil) | |
} | |
@available(*, unavailable) | |
required init?(coder: NSCoder) { | |
fatalError("\(#function) has not been implemented") | |
} | |
} | |
class ToViewController: UIViewController { | |
var label: UILabel = { | |
let view = UILabel(frame: .zero) | |
view.font = .preferredFont(forTextStyle: .largeTitle) | |
view.textColor = .red | |
view.translatesAutoresizingMaskIntoConstraints = false | |
view.text = "ToView" | |
view.textAlignment = .center | |
return view | |
}() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
self.view.backgroundColor = .lightGray.withAlphaComponent(0.15) | |
self.view.addSubview(label) | |
NSLayoutConstraint.activate([ | |
self.label.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16), | |
self.label.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16), | |
self.label.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 16), | |
self.label.bottomAnchor.constraint(lessThanOrEqualTo: self.view.bottomAnchor, constant: -16), | |
]) | |
} | |
init() { | |
super.init(nibName: nil, bundle: nil) | |
} | |
@available(*, unavailable) | |
required init?(coder: NSCoder) { | |
fatalError("\(#function) has not been implemented") | |
} | |
} | |
class AmountViewController: UIViewController { | |
var label: UILabel = { | |
let view = UILabel(frame: .zero) | |
view.font = .preferredFont(forTextStyle: .largeTitle) | |
view.textColor = .red | |
view.translatesAutoresizingMaskIntoConstraints = false | |
view.text = "AmountView" | |
view.textAlignment = .center | |
return view | |
}() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
self.view.backgroundColor = .lightGray.withAlphaComponent(0.15) | |
self.view.addSubview(label) | |
NSLayoutConstraint.activate([ | |
self.label.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 16), | |
self.label.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -16), | |
self.label.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 16), | |
self.label.bottomAnchor.constraint(lessThanOrEqualTo: self.view.bottomAnchor, constant: -16), | |
]) | |
} | |
init() { | |
super.init(nibName: nil, bundle: nil) | |
} | |
@available(*, unavailable) | |
required init?(coder: NSCoder) { | |
fatalError("\(#function) has not been implemented") | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment