diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 1f3e1d53..e9fd6b52 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -10,6 +10,7 @@ 0105618D224BBE7700E1557D /* FormValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618A224BBE7700E1557D /* FormValidator.swift */; }; 0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */; }; 0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */; }; + 01157B94225D376D00F15D92 /* RadioButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01157B93225D376D00F15D92 /* RadioButton.swift */; }; 0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0198F79E225679870066C936 /* FormValidationProtocol.swift */; }; 0198F7A62256A80B0066C936 /* MFRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 0198F7A02256A80A0066C936 /* MFRadioButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0198F7A22256A80A0066C936 /* MFRadioButton.m */; }; @@ -168,6 +169,7 @@ 0105618A224BBE7700E1557D /* FormValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidator.swift; sourceTree = ""; }; 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+TextFields.swift"; sourceTree = ""; }; 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+FormParams.swift"; sourceTree = ""; }; + 01157B93225D376D00F15D92 /* RadioButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RadioButton.swift; sourceTree = ""; }; 0198F79E225679870066C936 /* FormValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidationProtocol.swift; sourceTree = ""; }; 0198F7A02256A80A0066C936 /* MFRadioButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFRadioButton.h; sourceTree = ""; }; 0198F7A22256A80A0066C936 /* MFRadioButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFRadioButton.m; sourceTree = ""; }; @@ -442,6 +444,7 @@ D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */, D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */, D274CA322236A78900B01B62 /* StandardFooterView.swift */, + 01157B93225D376D00F15D92 /* RadioButton.swift */, ); path = Molecules; sourceTree = ""; @@ -560,6 +563,8 @@ D29DF17D21E69E26003B2FB9 /* Views */ = { isa = PBXGroup; children = ( + 0198F7A02256A80A0066C936 /* MFRadioButton.h */, + 0198F7A22256A80A0066C936 /* MFRadioButton.m */, DBC4391622442196001AB423 /* CaretView.swift */, DBC4391722442197001AB423 /* DashLine.swift */, D29DF17E21E69E2E003B2FB9 /* MFView.h */, @@ -898,6 +903,7 @@ D282AACB2243C61700C46919 /* ButtonView.swift in Sources */, 0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */, D29DF2AE21E7B3A4003B2FB9 /* MFTextView.m in Sources */, + 01157B94225D376D00F15D92 /* RadioButton.swift in Sources */, D29DF18121E69E50003B2FB9 /* MFView.m in Sources */, D29DF18321E69E54003B2FB9 /* SeparatorView.m in Sources */, D29DF17A21E69E1F003B2FB9 /* MFCustomButton.m in Sources */, diff --git a/MVMCoreUI/Atoms/Views/MFLabel.m b/MVMCoreUI/Atoms/Views/MFLabel.m index 5fb19037..60d42178 100644 --- a/MVMCoreUI/Atoms/Views/MFLabel.m +++ b/MVMCoreUI/Atoms/Views/MFLabel.m @@ -154,7 +154,9 @@ } + (nonnull MFLabel *)label { - return [[MFLabel alloc] initWithFrame:CGRectZero]; + MFLabel *labelToReturn = [[MFLabel alloc] initWithFrame:CGRectZero]; + labelToReturn.translatesAutoresizingMaskIntoConstraints = NO; + return labelToReturn; } #pragma mark - Setters diff --git a/MVMCoreUI/Molecules/RadioButton.swift b/MVMCoreUI/Molecules/RadioButton.swift new file mode 100644 index 00000000..7703b7dc --- /dev/null +++ b/MVMCoreUI/Molecules/RadioButton.swift @@ -0,0 +1,135 @@ +// +// RadioButton.swift +// MVMCoreUI +// +// Created by Suresh, Kamlesh on 4/9/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers open class RadioButton: ViewConstrainingView, FormValidationProtocol{ + + var moleculeJson: [AnyHashable: Any]? + var selectedRadioButton: MFRadioButton? + var selectedValue: String? + + // MARK: - Inits + public init() { + super.init(frame: .zero) + } + + public override init(frame: CGRect) { + super.init(frame: frame) + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + self.moleculeJson = json + + // Configure class properties with JSON values + guard let jsonDictionary = moleculeJson, + let optionsList = jsonDictionary.optionalArrayForKey("optionsList") else { + return + } + + if let delegateObject = delegateObject as? MVMCoreUIDelegateObject { + FormValidator.setupValidation(molecule: self, delegate: delegateObject.formValidationProtocol) + } + + var items:[UIView] = [] + for option in optionsList { + if let itemUI = createOptionItem(option as? [AnyHashable: Any]) { + items.append(itemUI) + } + } + + let verticalSpace = MFStyler.defaultVerticalPadding(forSize: MVMCoreUIUtility.getWidth()) + StackableViewController.populateView(self, + withUIArray: items) { (item) -> UIEdgeInsets in + return UIEdgeInsets(top: verticalSpace, + left: 0, + bottom: 0, + right: 0) + } + } + + func createOptionItem(_ optionJson: [AnyHashable: Any]?) -> UIView? { + + guard let json = optionJson else { + return nil + } + + let containerView = ViewConstrainingView.empty() + let radioButton = MFRadioButton() + radioButton.translatesAutoresizingMaskIntoConstraints = false + containerView.addSubview(radioButton) + + let label = MFLabel.commonLabel() + label.setWithJSON(json.dictionaryForKey(KeyLabel), delegateObject: nil, additionalData: nil) + containerView.addSubview(label) + + radioButton.leftAnchor.constraint(equalTo: containerView.leftAnchor, constant: 0).isActive = true + radioButton.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor, constant: PaddingOne).isActive = true + containerView.bottomAnchor.constraint(greaterThanOrEqualTo: radioButton.bottomAnchor, constant: PaddingOne).isActive = true + radioButton.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true + + label.leftAnchor.constraint(equalTo: radioButton.rightAnchor, constant: PaddingTwo).isActive = true + label.rightAnchor.constraint(equalTo: containerView.rightAnchor, constant: 0).isActive = true + label.topAnchor.constraint(greaterThanOrEqualTo: containerView.topAnchor, constant: PaddingOne).isActive = true + label.bottomAnchor.constraint(greaterThanOrEqualTo: containerView.bottomAnchor, constant: PaddingOne).isActive = true + label.centerYAnchor.constraint(equalTo: containerView.centerYAnchor).isActive = true + + addActionHandler(containerView, radioButton, json) + return containerView + } + + func addActionHandler(_ containerView: UIView, _ radioButton: MFRadioButton, _ optionJson: [AnyHashable: Any]) { + let dummyButton = MFCustomButton(frame: .zero) + dummyButton.translatesAutoresizingMaskIntoConstraints = false + containerView.addSubview(dummyButton) + NSLayoutConstraint.constraintPinSubview(toSuperview: dummyButton) + containerView.bringSubviewToFront(dummyButton) + + dummyButton.add({ (button) in + if let selectedbutton = self.selectedRadioButton { + selectedbutton.isSelected = false + } + self.selectedValue = optionJson.optionalStringForKey(KeyValue) + self.selectedRadioButton = radioButton + self.selectedRadioButton?.isSelected = true + }, for: .touchUpInside) + } + + func getColor( _ json: [AnyHashable: Any], _ key: String) -> UIColor? { + if let colorHex = json.optionalStringForKey(key) { + return UIColor.mfGet(forHex: colorHex) + } else { + return nil + } + } + + open override func setupView() { + super.setupView() + self.translatesAutoresizingMaskIntoConstraints = false + } + + // Used to check the validity of the field, to enable/disable the primary button. + @objc public func isValidField() -> Bool { + return selectedValue != nil + } + + // The Field name key value pair for sending to server + @objc public func formFieldName() -> String? { + return moleculeJson?.stringForkey("fieldKey") + } + + // The Feild value key value paid for sending to server + @objc public func formFieldValue() -> String? { + return selectedValue + } +} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index c1d7a36d..8c7a88ec 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -32,7 +32,8 @@ @"standardFooter": StandardFooterView.class, @"caretView": CaretView.class, @"caretButton": CaretButton.class, - @"textField" : MFTextField.class + @"textField" : MFTextField.class, + @"radioButton": RadioButton.class } mutableCopy]; }); return mapping;