Skip to content

Instantly share code, notes, and snippets.

@damodarnamala
Created August 1, 2023 06:51
Show Gist options
  • Save damodarnamala/088cabb5d49d72cc467c79ae3bc05f50 to your computer and use it in GitHub Desktop.
Save damodarnamala/088cabb5d49d72cc467c79ae3bc05f50 to your computer and use it in GitHub Desktop.
Adding DynamicForms
//
// 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