159 lines
5.3 KiB
Swift
159 lines
5.3 KiB
Swift
//
|
|
// TestViewController.swift
|
|
// VDSSample
|
|
//
|
|
// Created by Matt Bruce on 8/12/22.
|
|
//
|
|
|
|
import Foundation
|
|
import UIKit
|
|
import Combine
|
|
import VDS
|
|
|
|
struct User {
|
|
var firstName: String
|
|
var lastName: String
|
|
|
|
init(firstName: String, lastName: String) {
|
|
self.firstName = firstName
|
|
self.lastName = lastName
|
|
}
|
|
}
|
|
|
|
class TextFieldBindingCell: UIControl {
|
|
|
|
private let firstNameTextField = TextField()
|
|
private let lastNameTextField = TextField()
|
|
private var subscriptions = Set<AnyCancellable>()
|
|
|
|
var user: User {
|
|
User(firstName: firstNameTextField.text ?? "", lastName: lastNameTextField.text ?? "" )
|
|
}
|
|
|
|
init(user: User) {
|
|
super.init(frame: .zero)
|
|
firstNameTextField.text = user.firstName
|
|
lastNameTextField.text = user.lastName
|
|
|
|
translatesAutoresizingMaskIntoConstraints = false
|
|
firstNameTextField.translatesAutoresizingMaskIntoConstraints = false
|
|
lastNameTextField.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
addSubview(firstNameTextField)
|
|
addSubview(lastNameTextField)
|
|
|
|
firstNameTextField.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
|
|
firstNameTextField.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
|
|
firstNameTextField.topAnchor.constraint(equalTo: topAnchor).isActive = true
|
|
firstNameTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
|
|
|
|
lastNameTextField.topAnchor.constraint(equalTo: firstNameTextField.bottomAnchor, constant: 20).isActive = true
|
|
lastNameTextField.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
|
|
lastNameTextField.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
|
|
lastNameTextField.heightAnchor.constraint(equalToConstant: 50).isActive = true
|
|
lastNameTextField.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
|
|
|
|
firstNameTextField
|
|
.textPublisher
|
|
.sink { [weak self] _ in
|
|
self?.sendActions(for: .valueChanged)
|
|
}.store(in: &subscriptions)
|
|
|
|
lastNameTextField
|
|
.textPublisher
|
|
.sink { [weak self] _ in
|
|
self?.sendActions(for: .valueChanged)
|
|
}.store(in: &subscriptions)
|
|
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
}
|
|
|
|
@objcMembers class TestViewController: UIViewController, Initable {
|
|
deinit {
|
|
print("\(Self.self) deinit")
|
|
}
|
|
|
|
var user = User(firstName: "Joe", lastName: "User") {
|
|
didSet {
|
|
print("User oldValue: \(oldValue)")
|
|
print("User newValue: \(user)")
|
|
}
|
|
}
|
|
|
|
private var subscriptions = Set<AnyCancellable>()
|
|
|
|
required init() {
|
|
super.init(nibName: nil, bundle: nil)
|
|
}
|
|
|
|
required init?(coder: NSCoder) {
|
|
fatalError("init(coder:) has not been implemented")
|
|
}
|
|
|
|
override func viewDidLoad() {
|
|
super.viewDidLoad()
|
|
view.backgroundColor = .white
|
|
|
|
let nameTextField = TextFieldBindingCell(user: user)
|
|
let button = UIButton()
|
|
|
|
button.translatesAutoresizingMaskIntoConstraints = false
|
|
|
|
view.addSubview(nameTextField)
|
|
view.addSubview(button)
|
|
nameTextField.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20).isActive = true
|
|
nameTextField.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor, constant: -20).isActive = true
|
|
nameTextField.topAnchor.constraint(equalTo: view.safeAreaLayoutGuide.topAnchor, constant: 20).isActive = true
|
|
button.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor, constant: 20).isActive = true
|
|
button.topAnchor.constraint(equalTo: nameTextField.bottomAnchor, constant: 20).isActive = true
|
|
button.heightAnchor.constraint(equalToConstant: 50).isActive = true
|
|
button.widthAnchor.constraint(equalToConstant: 100).isActive = true
|
|
button.backgroundColor = .blue
|
|
button.setTitle("Print", for: .normal)
|
|
|
|
//publishers
|
|
nameTextField
|
|
.publisher(for: .valueChanged)
|
|
.sink(receiveValue: { [weak self] control in
|
|
guard let self else { return }
|
|
self.user = control.user
|
|
})
|
|
.store(in: &subscriptions)
|
|
|
|
button
|
|
.tapPublisher
|
|
.sink { [weak self] _ in
|
|
if let user = self?.user {
|
|
print("\(user.firstName) \(user.lastName)")
|
|
}
|
|
}.store(in: &subscriptions)
|
|
}
|
|
}
|
|
|
|
class TextField: UITextField {
|
|
var textPadding = UIEdgeInsets(
|
|
top: 10,
|
|
left: 20,
|
|
bottom: 10,
|
|
right: 20
|
|
)
|
|
|
|
override func textRect(forBounds bounds: CGRect) -> CGRect {
|
|
layer.borderColor = UIColor.black.cgColor
|
|
layer.borderWidth = 1
|
|
let rect = super.textRect(forBounds: bounds)
|
|
return rect.inset(by: textPadding)
|
|
}
|
|
|
|
override func editingRect(forBounds bounds: CGRect) -> CGRect {
|
|
layer.borderColor = UIColor.black.cgColor
|
|
layer.borderWidth = 1
|
|
let rect = super.editingRect(forBounds: bounds)
|
|
return rect.inset(by: textPadding)
|
|
}
|
|
}
|