// // Toggle.swift // MVMCoreUI // // Created by Kevin Christiano on 12/4/19. // Copyright © 2019 Verizon Wireless. All rights reserved. // import MVMCore import MVMCoreUI import UIKit import VDS ///----------------------------------------------------------------------------- ///MARK: -- VDSMoleculeViewProtocol (Contract between VDS -> Atomic) ///----------------------------------------------------------------------------- public protocol VDSMoleculeViewProtocol: MoleculeViewProtocol, MVMCoreViewProtocol { associatedtype ViewModel: MoleculeModelProtocol var viewModel: ViewModel! { get set } var delegateObject: MVMCoreUIDelegateObject? { get set } var additionalData: [AnyHashable: Any]? { get set } func viewModelDidUpdate() } extension VDSMoleculeViewProtocol { public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let castedModel = model as? ViewModel else { return } self.delegateObject = delegateObject viewModel = castedModel viewModelDidUpdate() } } ///----------------------------------------------------------------------------- ///MARK: -- TestToggleModel Extension ///----------------------------------------------------------------------------- extension TestToggleModel { ///Copy properties into a model the then drive the VDS Toggle public func getVDSModel() -> DefaultToggleModel { return DefaultToggleModel().copyWith { $0.disabled = !enabled && readOnly $0.on = selected if let accessibilityText = accessibilityText { $0.accessibilityLabelEnabled = accessibilityText $0.accessibilityLabelDisabled = accessibilityText } } } } ///----------------------------------------------------------------------------- ///MARK: -- TestToggle ///----------------------------------------------------------------------------- /// Class that will subclass VDS Toggle, however since our Atomic Toggle Model is a class (Due to EnableableProtocol) /// we have to split up the models, using ours and the DefaultToggleModel (internal to VDS control) /// - issuses: we have to then sync values from the internal DefaultToggleModel to the Atomic model since this /// is the model that talks to the validator open class TestToggle: ToggleBase, VDSMoleculeViewProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- public var viewModel: TestToggleModel! public var delegateObject: MVMCoreUIDelegateObject? public var additionalData: [AnyHashable: Any]? //-------------------------------------------------- // MARK: - Initializers //-------------------------------------------------- public override func initialSetup() { super.initialSetup() publisher(for: .touchUpInside) .sink {[weak self] toggle in guard let self = self else { return } self.toggle() }.store(in: &subscribers) publisher(for: .valueChanged) .sink {[weak self] toggle in guard let self = self else { return } self.valueChanged(isOn: toggle.isOn) }.store(in: &subscribers) model.accessibilityLabelEnabled = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel") model.accessibilityLabelDisabled = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel") model.accessibilityHintEnabled = MVMCoreUIUtility.hardcodedString(withKey: "AccToggleHint") model.accessibilityHintDisabled = MVMCoreUIUtility.hardcodedString(withKey: "AccDisabled") model.accessibilityValueEnabled = MVMCoreUIUtility.hardcodedString(withKey: "AccOn") model.accessibilityValueDisabled = MVMCoreUIUtility.hardcodedString(withKey: "AccOff") } // MARK:- MVMCoreViewProtocol open func updateView(_ size: CGFloat) {} open func viewModelDidUpdate() { guard let viewModel else { return } FormValidator.setupValidation(for: viewModel, delegate: delegateObject?.formHolderDelegate) additionalData = additionalData.dictionaryAdding(key: KeySourceModel, value: viewModel) set(with: viewModel.getVDSModel()) } private func valueChanged(isOn: Bool){ guard let viewModel else { return } //sync the value on the viewModel viewModel.selected = isOn //tell the form you changed _ = FormValidator.validate(delegate: self.delegateObject?.formHolderDelegate) if viewModel.action != nil || viewModel.alternateAction != nil { var action: ActionModelProtocol? if isOn { action = viewModel.action } else { action = viewModel.alternateAction ?? viewModel.action } if let action { MVMCoreUIActionHandler.performActionUnstructured(with: action, sourceModel: viewModel, additionalData: additionalData, delegateObject: delegateObject) } } print("toggle value changed to: \(isOn)") print("viewModel server value: \(viewModel.formFieldServerValue()!)") } public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { return 44 } private typealias ActionDefinition = (model: ActionModelProtocol, sourceModel: MoleculeModelProtocol?) private func performActionUnstructured(definition: ActionDefinition) { MVMCoreUIActionHandler.performActionUnstructured(with: definition.model, sourceModel: definition.sourceModel, additionalData: additionalData, delegateObject: delegateObject) } } // MARK: - MVMCoreUIViewConstrainingProtocol extension TestToggle: MVMCoreUIViewConstrainingProtocol { public func needsToBeConstrained() -> Bool { true } public func horizontalAlignment() -> UIStackView.Alignment { .trailing } }