Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //: Playground - noun: a place where people can play
- import UIKit
- import PlaygroundSupport
- protocol TextChangedEvent {
- func onTextChanged(_ closure: @escaping (String?) -> ()) -> Self
- }
- @objc class TextFieldChangeHandler: NSObject {
- private var closure: (String?) -> ()
- init(closure: @escaping (String?) -> ()) {
- self.closure = closure
- }
- @objc func change(_ textField: UITextField) {
- closure(textField.text)
- }
- }
- private var TextFieldChangeHandlerAssociatedObjectHandle: UInt8 = 0
- extension UITextField {
- func onTextChanged(_ closure: @escaping (String?) -> ()) -> Self {
- let context = TextFieldChangeHandler(closure: closure)
- objc_setAssociatedObject(self, &TextFieldChangeHandlerAssociatedObjectHandle, context, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
- addTarget(context, action: #selector(TextFieldChangeHandler.change), for: .editingChanged)
- return self
- }
- }
- protocol TapEvent {
- func onTap(_ closure: @escaping () -> ()) -> Self
- }
- @objc class TapContext: NSObject {
- private var closure: () -> ()
- init(closure: @escaping () -> ()) {
- self.closure = closure
- }
- @objc func press() {
- closure()
- }
- }
- private var TapContextAssociatedObjectHandle: UInt8 = 0
- extension UIButton: TapEvent {
- func onTap(_ closure: @escaping () -> ()) -> Self {
- let context = TapContext(closure: closure)
- objc_setAssociatedObject(self, &TapContextAssociatedObjectHandle, context, objc_AssociationPolicy.OBJC_ASSOCIATION_RETAIN_NONATOMIC)
- addTarget(context, action: #selector(TapContext.press), for: .touchUpInside)
- return self
- }
- }
- protocol Initializable {
- init()
- }
- func createInstance<T>(_ type: T.Type) -> T where T: Initializable {
- return type.init()
- }
- extension UIView: Initializable { }
- extension UIControl: Initializable { }
- func component<T: Initializable>(_ type: T.Type, configuration: (T) -> ()) -> T {
- let instance: T = createInstance(type)
- configuration(instance)
- return instance
- }
- protocol Handler {
- func login()
- func changePassword(_ text: String?)
- func changeEmail(_ text: String?)
- }
- class MockHandler: Handler {
- func login() {
- print("Login pressed")
- }
- func changeEmail(_ text: String?) {
- print("Changed email to \(text)")
- }
- func changePassword(_ text: String?) {
- print("Changed password to \(text)")
- }
- }
- let handler: Handler = MockHandler()
- let email = component(UITextField.self) {
- $0.translatesAutoresizingMaskIntoConstraints = false
- $0.placeholder = "Email"
- $0.keyboardType = .emailAddress
- $0.returnKeyType = .next
- $0.autocapitalizationType = .none
- $0.autocorrectionType = .no
- $0.onTextChanged(handler.changeEmail(_:))
- }
- let password = component(UITextField.self) {
- $0.translatesAutoresizingMaskIntoConstraints = false
- $0.placeholder = "Password"
- $0.keyboardType = .default
- $0.returnKeyType = .send
- $0.isSecureTextEntry = true
- $0.autocapitalizationType = .none
- $0.autocorrectionType = .no
- $0.onTextChanged(handler.changePassword(_:))
- }
- let button = component(UIButton.self) {
- $0.translatesAutoresizingMaskIntoConstraints = false
- $0.setTitle("Login", for: .normal)
- $0.backgroundColor = .gray
- $0.layer.borderWidth = 1 / UIScreen.main.scale
- $0.layer.borderColor = UIColor.black.cgColor
- $0.onTap(handler.login)
- }
- let view = component(UIView.self) {
- $0.frame = CGRect(x: 0, y: 0, width: 300, height: 230)
- $0.backgroundColor = .white
- $0.addSubview(email)
- $0.addSubview(password)
- $0.addSubview(button)
- NSLayoutConstraint.activate([
- email.leadingAnchor.constraint(equalTo: $0.leadingAnchor, constant: 20), email.trailingAnchor.constraint(equalTo: $0.trailingAnchor, constant: -20), email.topAnchor.constraint(equalTo: $0.topAnchor, constant: 20), email.heightAnchor.constraint(equalToConstant: 44),
- password.leadingAnchor.constraint(equalTo: $0.leadingAnchor, constant: 20), password.trailingAnchor.constraint(equalTo: $0.trailingAnchor, constant: -20), password.topAnchor.constraint(equalTo: email.bottomAnchor, constant: 20), password.heightAnchor.constraint(equalToConstant: 44),
- button.leadingAnchor.constraint(equalTo: $0.leadingAnchor, constant: 20), button.trailingAnchor.constraint(equalTo: $0.trailingAnchor, constant: -20), button.topAnchor.constraint(equalTo: password.bottomAnchor, constant: 20), button.heightAnchor.constraint(equalToConstant: 60)
- ])
- }
- PlaygroundPage.current.liveView = view
- email.text = "test@email.com"
- password.text = "password123"
- button.sendActions(for: .touchUpInside)
Add Comment
Please, Sign In to add comment