code review

This commit is contained in:
Suresh, Kamlesh 2019-06-24 10:47:43 -04:00
parent 9316343c0e
commit 8eae881bf1
6 changed files with 53 additions and 135 deletions

View File

@ -16,7 +16,7 @@ import UIKit
var extraValidationBlock: (() -> Bool)? var extraValidationBlock: (() -> Bool)?
var radioButtonsModelByGroup: [String: RadioButtonModel] = [:] var radioButtonsModelByGroup: [String: RadioButtonModel] = [:]
public func insertMolecule(_ molecule: FormValidationProtocol) { public func insertMolecule(_ molecule: FormValidationProtocol) {
molecules.append(molecule) molecules.append(molecule)
} }

View File

@ -45,22 +45,35 @@ import UIKit
radioButton.translatesAutoresizingMaskIntoConstraints = false radioButton.translatesAutoresizingMaskIntoConstraints = false
addSubview(radioButton) addSubview(radioButton)
isAccessibilityElement = true
accessibilityTraits = .none
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "radio_action_hint")
radioButton.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor, constant: 0).isActive = true radioButton.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor, constant: 0).isActive = true
radioButton.topAnchor.constraint(greaterThanOrEqualTo: topAnchor, constant: PaddingOne).isActive = true var constraint = radioButton.topAnchor.constraint(greaterThanOrEqualTo: topAnchor, constant: PaddingOne)
bottomAnchor.constraint(greaterThanOrEqualTo: radioButton.bottomAnchor, constant: PaddingOne).isActive = true constraint.priority = .defaultLow
constraint.isActive = true
constraint = bottomAnchor.constraint(greaterThanOrEqualTo: radioButton.bottomAnchor, constant: PaddingOne)
constraint.priority = .defaultLow
constraint.isActive = true
radioButton.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true radioButton.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
if let rightView = createRightView() { if let rightView = createRightView() {
addSubview(rightView) addSubview(rightView)
rightView.leftAnchor.constraint(equalTo: radioButton.rightAnchor, constant: PaddingHorizontalBetweenRelatedItems).isActive = true rightView.leftAnchor.constraint(equalTo: radioButton.rightAnchor, constant: PaddingHorizontalBetweenRelatedItems).isActive = true
rightView.rightAnchor.constraint(equalTo: layoutMarginsGuide.rightAnchor, constant: 0).isActive = true rightView.rightAnchor.constraint(equalTo: layoutMarginsGuide.rightAnchor, constant: 0).isActive = true
rightView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor, constant: PaddingOne).isActive = true
rightView.bottomAnchor.constraint(greaterThanOrEqualTo: bottomAnchor, constant: PaddingOne).isActive = true constraint = rightView.topAnchor.constraint(equalTo: topAnchor, constant: PaddingOne)
rightView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true constraint.priority = .defaultHigh
constraint.isActive = true
constraint = bottomAnchor.constraint(greaterThanOrEqualTo: rightView.bottomAnchor, constant: PaddingOne)
constraint.priority = .defaultHigh
constraint.isActive = true
} }
addActionHandler() addActionHandler()
addActionHandler()
} }
func createRightView() -> ViewConstrainingView? { func createRightView() -> ViewConstrainingView? {
@ -92,7 +105,8 @@ import UIKit
} else { } else {
radioButton.isSelected = !radioButton.isSelected radioButton.isSelected = !radioButton.isSelected
} }
FormValidator.enableByValidationWith(delegate: self.delegateObject?.formValidationProtocol) FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol)
changeAccessibilityLabel()
} }
} }
@ -113,20 +127,21 @@ extension RadioButton {
self.delegateObject = delegateObject self.delegateObject = delegateObject
radioButtonModel = RadioButtonModel.setupForRadioButtonGroup(radioButton: self, radioButtonModel = RadioButtonModel.setupForRadioButtonGroup(radioButton: self,
formValidator: self.delegateObject?.formValidationProtocol?.formValidatorModel?()) formValidator: delegateObject?.formValidationProtocol?.formValidatorModel?())
/* If the radio button has a group, it will have RadioButtonModel. /* If the radio button has a group, it will have RadioButtonModel.
In this case the RadioButtonModel should be the validator In this case the RadioButtonModel should be the validator
*/ */
if let radioButtonModel = radioButtonModel { if let radioButtonModel = radioButtonModel {
FormValidator.setupValidation(molecule: radioButtonModel, delegate: self.delegateObject?.formValidationProtocol) FormValidator.setupValidation(molecule: radioButtonModel, delegate: delegateObject?.formValidationProtocol)
} else { } else {
FormValidator.setupValidation(molecule: self, delegate: self.delegateObject?.formValidationProtocol) FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
} }
label.setWithJSON(jsonDictionary.optionalDictionaryForKey(KeyLabel), label.setWithJSON(jsonDictionary.optionalDictionaryForKey(KeyLabel),
delegateObject: delegateObject, delegateObject: delegateObject,
additionalData: additionalData) additionalData: additionalData)
changeAccessibilityLabel()
} }
} }
@ -146,8 +161,19 @@ extension RadioButton: FormValidationProtocol {
return radioButtonModel?.formFieldName() ?? json?.optionalStringForKey("fieldKey") return radioButtonModel?.formFieldName() ?? json?.optionalStringForKey("fieldKey")
} }
// The Feild value key value paid for sending to server // The Field value key value pair for sending to server
@objc public func formFieldValue() -> Any? { @objc public func formFieldValue() -> Any? {
return radioButtonModel?.formFieldValue() ?? radioButton.isSelected return radioButtonModel?.formFieldValue() ?? radioButton.isSelected
} }
} }
// MARK: Accessibility
extension RadioButton {
func changeAccessibilityLabel() {
let stateString = radioButton.isSelected ? "radio_selected_state" : "radio_not_selected_state"
let localizedStringState = MVMCoreUIUtility.hardcodedString(withKey: stateString) ?? ""
let accebilityString = (label.accessibilityLabel ?? (json?.optionalStringForKey("accessibilityText") ?? ""))
+ (MVMCoreUIUtility.hardcodedString(withKey: "radio_desc_state") ?? "") + localizedStringState
accessibilityLabel = accebilityString
}
}

View File

@ -1,113 +0,0 @@
//
// RadioButton.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 4/9/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import UIKit
@objc public protocol RadioButtonListProtocol: NSObjectProtocol {
@objc optional func selected(_ radioButton: RadioButton)
}
@objcMembers open class RadioButtonList: ViewConstrainingView, RadioButtonListProtocol {
var selectedRadioButton: RadioButton?
var selectedValue: String?
var delegateObject:MVMCoreUIDelegateObject?
// 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)
}
public func selected(_ radioButton: RadioButton) {
selectedRadioButton?.radioButton.isSelected = false
selectedRadioButton = radioButton
selectedRadioButton?.radioButton.isSelected = true
FormValidator.enableByValidationWith(delegate: self.delegateObject?.formValidationProtocol)
}
open override func setupView() {
super.setupView()
self.translatesAutoresizingMaskIntoConstraints = false
}
}
// MARK: - FormValidationProtocol
extension RadioButtonList: FormValidationProtocol {
// Used to check the validity of the field, to enable/disable the primary button.
@objc public func isValidField() -> Bool {
if !(json?.boolForKey("required") ?? true) {
return true
}
return selectedRadioButton != nil
}
// The Field name key value pair for sending to server
@objc public func formFieldName() -> String? {
return json?.optionalStringForKey("fieldKey")
}
// The Feild value key value paid for sending to server
@objc public func formFieldValue() -> Any? {
return selectedRadioButton?.formFieldValue()
}
}
// MARK: - MVMCoreUIMoleculeViewProtocol
extension RadioButtonList {
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
// Configure class properties with JSON values
guard let jsonDictionary = json,
let optionsList = jsonDictionary.optionalArrayForKey("optionsList") as? [[AnyHashable: Any]],
let delegateObject = delegateObject as? MVMCoreUIDelegateObject else {
return
}
self.delegateObject = delegateObject
FormValidator.setupValidation(molecule: self, delegate: delegateObject.formValidationProtocol)
StackableViewController.remove(self.subviews)
var items:[UIView] = []
for option in optionsList {
let radioButton = RadioButton(target: self)
radioButton.setWithJSON(option, delegateObject: delegateObject, additionalData: nil)
items.append(radioButton)
}
let verticalSpace = MFStyler.defaultVerticalPaddingForApplicationWidth()
StackableViewController.populateView(self,
withUIArray: items) { (item) -> UIEdgeInsets in
return UIEdgeInsets(top: verticalSpace,
left: 0,
bottom: 0,
right: 0)
}
}
open override func needsToBeConstrained() -> Bool {
return true
}
open override func moleculeAlignment() -> UIStackView.Alignment {
return UIStackView.Alignment.leading;
}
}

View File

@ -35,8 +35,6 @@ extern CGFloat const PaddingHorizontalLarge;
extern CGFloat const PaddingVerticalWhiteGrayView; extern CGFloat const PaddingVerticalWhiteGrayView;
extern CGFloat const PaddingVerticalHeadlineAlternate; extern CGFloat const PaddingVerticalHeadlineAlternate;
extern CGFloat const PaddingPrimaryButtonTop; extern CGFloat const PaddingPrimaryButtonTop;
//
extern CGFloat const PaddingHorizontalBetweenRelatedItems; extern CGFloat const PaddingHorizontalBetweenRelatedItems;
// These are based on the multiple of 6 rule // These are based on the multiple of 6 rule

View File

@ -35,6 +35,13 @@
"checkbox_checked_state" = "Checked"; "checkbox_checked_state" = "Checked";
"checkbox_unchecked_state" = "Unchecked"; "checkbox_unchecked_state" = "Unchecked";
"checkbox_desc_state" = "%@ CheckBox %@"; "checkbox_desc_state" = "%@ CheckBox %@";
// Radio Button
"radio_action_hint" = "Double tap to select";
"radio_selected_state" = "Selected";
"radio_not_selected_state" = "Not Selected";
"radio_desc_state" = "Option";
// Switch // Switch
"mfswitch_buttonlabel" = "Switch Button"; "mfswitch_buttonlabel" = "Switch Button";
"AccOn" = "on"; "AccOn" = "on";

View File

@ -8,9 +8,9 @@
import UIKit import UIKit
public class MoleculeStackTemplate: ThreeLayerViewController { open class MoleculeStackTemplate: ThreeLayerViewController {
public override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool { open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
var shouldFinish = super.shouldFinishProcessingLoad(loadObject, error: error) var shouldFinish = super.shouldFinishProcessingLoad(loadObject, error: error)
if shouldFinish, let firstError = modulesNeeded().errors?.first { if shouldFinish, let firstError = modulesNeeded().errors?.first {
// Don't continue if there was an error loading needed modules. // Don't continue if there was an error loading needed modules.
@ -20,25 +20,25 @@ public class MoleculeStackTemplate: ThreeLayerViewController {
return shouldFinish return shouldFinish
} }
public override func spaceBetweenTopAndMiddle() -> CGFloat? { open override func spaceBetweenTopAndMiddle() -> CGFloat? {
return 0 return 0
} }
public override func viewForTop() -> UIView? { open override func viewForTop() -> UIView? {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else { guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else {
return nil return nil
} }
return molecule return molecule
} }
public override func viewForMiddle() -> UIView? { open override func viewForMiddle() -> UIView? {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("moleculeStack") else { guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("moleculeStack") else {
return nil return nil
} }
return MoleculeStackView(withJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil) return MoleculeStackView(withJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
} }
override public func viewForBottom() -> UIView? { override open func viewForBottom() -> UIView? {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else { guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else {
return nil return nil
} }
@ -46,14 +46,14 @@ public class MoleculeStackTemplate: ThreeLayerViewController {
} }
// MARK: - cache handling // MARK: - cache handling
public override func pageTypesToListenFor() -> [Any]? { open override func pageTypesToListenFor() -> [Any]? {
guard let pageType = self.pageType else { guard let pageType = self.pageType else {
return super.pageTypesToListenFor() return super.pageTypesToListenFor()
} }
return [pageType] return [pageType]
} }
public override func modulesToListenFor() -> [Any]? { open override func modulesToListenFor() -> [Any]? {
// Get all of the molecules that need modules. // Get all of the molecules that need modules.
return modulesNeeded().modules return modulesNeeded().modules
} }