vds_ios_sample/VDSSample/ViewControllers/TestViewController.swift
Matt Bruce 11ad080a69 added test sample
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
2022-08-12 12:53:23 -05:00

176 lines
6.2 KiB
Swift

//
// TestViewController.swift
// VDSSample
//
// Created by Matt Bruce on 8/12/22.
//
import Foundation
import UIKit
import Combine
class User: ObservableObject {
var firstName: String
var lastName: String
init(firstName: String, lastName: String) {
self.firstName = firstName
self.lastName = lastName
}
}
class TextFieldCell: UIView {
let firstNameTextField = TextField()
let lastNameTextField = TextField()
var subject: CurrentValueSubject<User, Never>
private var subscriptions = Set<AnyCancellable>()
var model: User
private func send() {
subject.send(model)
}
init(subject: CurrentValueSubject<User, Never>) {
self.model = subject.value
self.subject = subject
super.init(frame: .zero)
translatesAutoresizingMaskIntoConstraints = false
firstNameTextField.translatesAutoresizingMaskIntoConstraints = false
lastNameTextField.translatesAutoresizingMaskIntoConstraints = false
addSubview(firstNameTextField)
addSubview(lastNameTextField)
print("\(model.firstName) \(model.lastName)")
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
//add the logic
let firstNameSubject = CurrentValueSubject<String, Never>(model.firstName)
firstNameTextField.createBinding(with: firstNameSubject, storeIn: &subscriptions)
firstNameSubject.assign(to: \.model.firstName, on: self).store(in: &subscriptions)
firstNameSubject.sink {[weak self] value in
self?.send()
}.store(in: &subscriptions)
let lastNameSubject = CurrentValueSubject<String, Never>(model.lastName)
lastNameTextField.createBinding(with: lastNameSubject, storeIn: &subscriptions)
lastNameSubject.assign(to: \.model.lastName, on: self).store(in: &subscriptions)
lastNameSubject.sink {[weak self] value in
guard let self = self else { return }
self.send()
}.store(in: &subscriptions)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
@objcMembers class TestViewController: UIViewController, Initable {
var user = User(firstName: "Joe", lastName: "User")
var nameTextField: TextFieldCell!
var button = UIButton()
private var cancellables = 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 subject = CurrentValueSubject<User, Never>(user)
subject.assign(to: \.user, on: self).store(in: &cancellables)
nameTextField = TextFieldCell(subject: subject)
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)
button.addAction(UIAction(title: "", handler: { [weak self] action in
if let user = self?.user {
print("\(user.firstName) \(user.lastName)")
}
}), for: .touchUpInside)
}
}
extension UITextField {
func textPublisher() -> AnyPublisher<String, Never> {
NotificationCenter.default
.publisher(for: UITextField.textDidChangeNotification, object: self)
.compactMap({ ($0.object as? UITextField)?.text })
.eraseToAnyPublisher()
}
func createBinding(with subject: CurrentValueSubject<String, Never>,
storeIn subscriptions: inout Set<AnyCancellable>) {
subject.sink { [weak self] (value) in
if value != self?.text {
self?.text = value
}
}.store(in: &subscriptions)
self.textPublisher().sink { (value) in
if value != subject.value {
subject.send(value)
}
}.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)
}
}