// // WifiWidgetMolecule.swift // MVMFrameworksSample // // Created by Matt Bruce on 6/17/22. // import Foundation import UIKit import MVMCore import MVMCoreUI @objcMembers open class TestLabelToggle: View { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- public let label = Label(fontStyle: .BoldBodySmall) public let toggle = TestToggle() //-------------------------------------------------- // MARK: - MVMCoreViewProtocol //-------------------------------------------------- open override func updateView(_ size: CGFloat) { super.updateView(size) label.updateView(size) toggle.updateView(size) } open override func setupView() { super.setupView() addSubview(label) addSubview(toggle) label.setContentHuggingPriority(.required, for: .vertical) NSLayoutConstraint.pinViews(leftView: label, rightView: toggle, alignTop: false) } open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { guard let model = model as? TestLabelToggleModel, let toggleHeight = Toggle.estimatedHeight(with: model.toggle, delegateObject), let labelHeight = Label.estimatedHeight(with: model.label, delegateObject) else { return nil } return max(toggleHeight, labelHeight) } open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let labelToggleModel = model as? TestLabelToggleModel else { return } label.set(with: labelToggleModel.label, delegateObject, additionalData) toggle.set(with: labelToggleModel.toggle, delegateObject, additionalData) } // MARK: - MoleculeViewProtocol open override func reset() { super.reset() label.reset() toggle.reset() label.setFontStyle(.BoldBodySmall) } } public class TestLabelToggleModel: MoleculeModelProtocol { public static var identifier: String = "testLabelToggle" public var moleculeName: String = TestLabelToggleModel.identifier public var backgroundColor: Color? public var label: LabelModel public var toggle: TestToggleModel public init(_ label: LabelModel, _ toggle: TestToggleModel) { self.label = label self.toggle = toggle } private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor case label case toggle } required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey:.backgroundColor) label = try typeContainer.decode(LabelModel.self, forKey:.label) toggle = try typeContainer.decode(TestToggleModel.self, forKey:.toggle) } public func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encode(moleculeName, forKey: .moleculeName) try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor) try container.encode(label, forKey: .label) try container.encode(toggle, forKey: .toggle) } } public class WifiWidget: View { //-------------------------------------------------- // MARK: - Outlets //-------------------------------------------------- public private(set) var titleLabelToggle: TestLabelToggle = { let tlt = TestLabelToggle() tlt.label.setFontStyle(.BoldBodyLarge) return tlt }() public let descriptionLabel = Label(fontStyle: .RegularMicro) public let passwordTextField = TextEntryField() public let editTitleLink = Link() public let shareTitleLink = Link() private lazy var stack1: Stack = { return Stack.createStack(with: [titleLabelToggle, descriptionLabel], axis: .vertical, spacing: Padding.Two) }() private lazy var stack2: Stack = { return Stack.createStack(with: [ (view: editTitleLink, model: StackItemModel()), (view: shareTitleLink, model: StackItemModel(horizontalAlignment: .trailing)) ], axis: .horizontal, spacing: Padding.Two) }() private var row2 = StackItemModel() private var row3 = StackItemModel() private lazy var stack: Stack = { let model = StackModel(molecules: [StackItemModel(), row2, row3], axis: .vertical, spacing: Padding.Four) let stackItems = [StackItem(andContain:stack1), StackItem(andContain: passwordTextField), StackItem(andContain:stack2)] return Stack(with: model, stackItems: stackItems) }() //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- /// Initial configuration of class and view. @objc final public override func setupView() { super.setupView() isAccessibilityElement = false setContentCompressionResistancePriority(.required, for: .vertical) accessibilityElements = [titleLabelToggle.label, descriptionLabel, editTitleLink, shareTitleLink] stack1.restack() stack2.restack() stack.restack() stack.backgroundColor = .clear addSubview(stack) NSLayoutConstraint.constraintPinSubview(stack, pinTop: true, topConstant: 16, pinBottom: true, bottomConstant: 16, pinLeft: true, leftConstant: 16, pinRight: true, rightConstant: 16) } open override func reset() { super.reset() stack.reset() } open func restack(){ stack1.restack() stack2.restack() stack.restack() } open override func updateView(_ size: CGFloat) { super.updateView(size) stack.updateView(size) } //------------------------------------------------------ // MARK: - Atomization //------------------------------------------------------ open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) guard let model = model as? WifiWidgetModel else { return } backgroundColor = model.backgroundColor?.uiColor ?? .mvmCoolGray1 //Password Text Field Model passwordTextField.set(with: model.passwordModel, delegateObject, additionalData) //Update the Stacks with the models stack1.updateContainedMolecules(with: [model.titleModel, model.descriptionModel], delegateObject, additionalData) stack2.updateContainedMolecules(with: [model.editModel, model.shareModel], delegateObject, additionalData) //show/hide 2 and 3 rows row2.gone = !model.enabled row3.gone = !model.enabled stack.restack() } }