Merge branch 'feature/doughnutchart_from_coding' of gitlab.verizon.com:BPHV_MIPS/mvm_core_ui into feature/doughnutchart_from_coding

This commit is contained in:
Suresh, Kamlesh 2020-01-15 19:37:20 -05:00
commit ab14a9360a
16 changed files with 514 additions and 25 deletions

View File

@ -50,6 +50,7 @@
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 */; };
01C851D323CF9E740021F976 /* LabelToggleModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01C851D223CF9E740021F976 /* LabelToggleModel.swift */; };
01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; };
01EB3684236097C0006832FA /* MoleculeProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB3683236097C0006832FA /* MoleculeProtocol.swift */; };
01EB368F23609801006832FA /* LabelModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01EB368823609801006832FA /* LabelModel.swift */; };
@ -81,6 +82,7 @@
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; };
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; };
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0AA33B392398524F0067DD0F /* Toggle.swift */; };
0ABD136B237B193A0081388D /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136A237B193A0081388D /* EntryFieldContainer.swift */; };
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; };
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; };
@ -335,6 +337,7 @@
0198F79E225679870066C936 /* FormValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidationProtocol.swift; sourceTree = "<group>"; };
0198F7A02256A80A0066C936 /* MFRadioButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFRadioButton.h; sourceTree = "<group>"; };
0198F7A22256A80A0066C936 /* MFRadioButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFRadioButton.m; sourceTree = "<group>"; };
01C851D223CF9E740021F976 /* LabelToggleModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelToggleModel.swift; sourceTree = "<group>"; };
01EB3683236097C0006832FA /* MoleculeProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MoleculeProtocol.swift; sourceTree = "<group>"; };
01EB368823609801006832FA /* LabelModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LabelModel.swift; sourceTree = "<group>"; };
01EB368923609801006832FA /* ListItemModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListItemModel.swift; sourceTree = "<group>"; };
@ -355,6 +358,7 @@
0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = "<group>"; };
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = "<group>"; };
0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxWithLabelView.swift; sourceTree = "<group>"; };
0AA33B392398524F0067DD0F /* Toggle.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toggle.swift; sourceTree = "<group>"; };
0A8321AE2355FE9500CB7F00 /* DigitBox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DigitBox.swift; sourceTree = "<group>"; };
0AA33B33239813C50067DD0F /* UIColor+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+Extension.swift"; sourceTree = "<group>"; };
0ABD136A237B193A0081388D /* EntryFieldContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
@ -764,6 +768,7 @@
children = (
01509D942327ED1900EF99AA /* HeadlineBodyTextButtonSwitch.swift */,
D22479892314445E003FCCF9 /* LabelSwitch.swift */,
01C851D223CF9E740021F976 /* LabelToggleModel.swift */,
D224798B231450C8003FCCF9 /* HeadlineBodySwitch.swift */,
);
path = SwitchMolecules;
@ -1116,6 +1121,7 @@
D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */,
943784F3236B77BB006A1E82 /* GraphView.swift */,
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */,
0AA33B392398524F0067DD0F /* Toggle.swift */,
);
path = Views;
sourceTree = "<group>";
@ -1438,6 +1444,7 @@
D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */,
D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */,
D2B18B7F2360913400A9AEDC /* Control.swift in Sources */,
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */,
D29DF12F21E6851E003B2FB9 /* MVMCoreUITopAlertMainView.m in Sources */,
012A88C8238DB02000FE3DA1 /* ModelMoleculeDelegateProtocol.swift in Sources */,
DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */,
@ -1446,6 +1453,7 @@
9445890C2385BCE300DE9FD4 /* ProgressBarModel.swift in Sources */,
D29DF17C21E69E1F003B2FB9 /* MFTextButton.m in Sources */,
9445891F2385D2E900DE9FD4 /* CaretViewModel.swift in Sources */,
01C851D323CF9E740021F976 /* LabelToggleModel.swift in Sources */,
D29DF2C521E7BF57003B2FB9 /* MFTabBarSwipeAnimator.m in Sources */,
012A88AD238C418100FE3DA1 /* TemplateProtocol.swift in Sources */,
D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */,

View File

@ -112,7 +112,9 @@ import UIKit
//if number of colors is even, need to display gradient layer, otherwise make top layer as solid color layer
if graphObject.colors.count % 2 == 0 {
leftColors.removeLast()
topLayer.colors = [leftColors.last!, rightColors.first!]
let firstColor = leftColors.last!.uiColor.cgColor
let secondColor = rightColors.first!.uiColor.cgColor
topLayer.colors = [firstColor, secondColor]
} else {
topLayer.backgroundColor = leftColors.last?.uiColor.cgColor
}
@ -125,7 +127,9 @@ import UIKit
//count of graidentLayer.colors must be bigger than 1, otherwise set backgroundColor
if leftColors.count > 1 {
leftLayer.colors = Array(leftColors)
leftLayer.colors = leftColors.map({ (color) -> CGColor in
return color.uiColor.cgColor
})
} else {
leftLayer.backgroundColor = leftColors.first?.uiColor.cgColor
}
@ -136,7 +140,9 @@ import UIKit
rightLayer.startPoint = CGPoint(x: 0, y: 0)
rightLayer.endPoint = CGPoint(x: 0, y: 1)
if rightColors.count > 1 {
rightLayer.colors = Array(rightColors)
rightLayer.colors = rightColors.map({ (color) -> CGColor in
return color.uiColor.cgColor
})
} else {
rightLayer.backgroundColor = rightColors.first?.uiColor.cgColor
}

View File

@ -9,7 +9,7 @@
import UIKit
@objcMembers public class LeftRightLabelModel: MoleculeProtocol {
public static var identifier: String = "leftRightLabel"
public static var identifier: String = "leftRightLabelView"
public var backgroundColor: Color?
public var leftText: LabelModel
public var rightText: LabelModel

View File

@ -17,7 +17,7 @@ extension MVMCoreUISwitch: ModelMoleculeViewProtocol {
FormValidator.setupValidation(molecule: castSelf, delegate: delegateObject?.formValidationProtocol)
}
setState(model.on, animated: false)
setState(model.state, animated: false)
guard let action = model.action else { return }
actionBlock = {

View File

@ -423,16 +423,16 @@ const CGFloat SwitchShakeIntensity = 2;
return UIAccessibilityTraitButton;
}
- (NSString * _Nullable)formFieldGroupName {
return [self.json string:@"groupName"];
}
- (NSString *)accessibilityHint {
return [MVMCoreUIUtility hardcodedStringWithKey:@"AccToggleHint"];
}
#pragma mark FormValidationProtocol
- (NSString * _Nullable)formFieldGroupName {
return [self.json string:@"groupName"];
}
- (BOOL)isValidField {
return self.isOn && [self.json boolForKey:@"required"];
}

View File

@ -0,0 +1,425 @@
//
// Toggle.swift
// MVMCoreUI
//
// Created by Kevin Christiano on 12/4/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import MVMCore
import UIKit
public typealias ActionBlockConfirmation = () -> (Bool)
/**
A custom implementation of Apple's UISwitch.
By default this class begins in the off state.
Container: The background of the toggle control.
Knob: The circular indicator that slides on the container.
*/
@objcMembers open class Toggle: Control, MVMCoreUIViewConstrainingProtocol, FormValidationFormFieldProtocol {
//--------------------------------------------------
// MARK: - Properties
//--------------------------------------------------
/// Holds the on and off colors for the container.
public var containerTintColor: (on: UIColor?, off: UIColor?)? = (on: .mfShamrock(), off: .black)
/// Holds the on and off colors for the knob.
public var knobTintColor: (on: UIColor?, off: UIColor?)? = (on: .white, off: .white)
/// Holds the on and off colors for the disabled state..
public var disabledTintColor: (container: UIColor?, knob: UIColor?)? = (container: .mfSilver(), knob: .white)
/// Set this flag to false if you do not want to animate state changes.
public var isAnimated = true
public var didToggleAction: ActionBlock?
/// Executes logic before state change. If false, then toggle state will not change and the didToggleAction will not execute.
public var shouldToggleAction: ActionBlockConfirmation? = {
return { return true }
}()
// Sizes are from InVision design specs.
static let containerSize = CGSize(width: 46, height: 24)
static let knobSize = CGSize(width: 22, height: 22)
private var knobView: View = {
let view = View()
view.backgroundColor = .white
view.layer.cornerRadius = Toggle.getKnobHeight() / 2.0
return view
}()
//--------------------------------------------------
// MARK: - Computed Properties
//--------------------------------------------------
open override var isEnabled: Bool {
didSet {
isUserInteractionEnabled = isEnabled
changeStateNoAnimation(isEnabled ? isOn : false)
backgroundColor = isEnabled ? containerTintColor?.off : disabledTintColor?.container
knobView.backgroundColor = isEnabled ? knobTintColor?.off : disabledTintColor?.knob
}
}
/// Simple means to prevent user interaction with the toggle.
public var isLocked: Bool = false {
didSet {
isUserInteractionEnabled = !isLocked
}
}
/// The state on the toggle. Default value: false.
open var isOn: Bool = false {
didSet {
if isAnimated {
UIView.animate(withDuration: 0.2, delay: 0.0, options: .curveEaseIn, animations: {
if self.isOn {
self.knobView.backgroundColor = self.knobTintColor?.on
self.backgroundColor = self.containerTintColor?.on
} else {
self.knobView.backgroundColor = self.knobTintColor?.off
self.backgroundColor = self.containerTintColor?.off
}
}, completion: nil)
UIView.animate(withDuration: 0.33, delay: 0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.2, options: [], animations: {
self.constrainKnob()
self.knobWidthConstraint?.constant = Self.getKnobWidth()
self.layoutIfNeeded()
}, completion: nil)
} else {
backgroundColor = isOn ? containerTintColor?.on : containerTintColor?.off
knobView.backgroundColor = isOn ? knobTintColor?.on : knobTintColor?.off
self.constrainKnob()
}
FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol)
accessibilityValue = isOn ? MVMCoreUIUtility.hardcodedString(withKey: "AccOn") : MVMCoreUIUtility.hardcodedString(withKey: "AccOff")
setNeedsLayout()
layoutIfNeeded()
}
}
//--------------------------------------------------
// MARK: - Delegate
//--------------------------------------------------
private var delegateObject: MVMCoreUIDelegateObject?
//--------------------------------------------------
// MARK: - Constraints
//--------------------------------------------------
private var knobLeadingConstraint: NSLayoutConstraint?
private var knobTrailingConstraint: NSLayoutConstraint?
private var knobHeightConstraint: NSLayoutConstraint?
private var knobWidthConstraint: NSLayoutConstraint?
private var heightConstraint: NSLayoutConstraint?
private var widthConstraint: NSLayoutConstraint?
private func constrainKnob() {
knobLeadingConstraint?.isActive = !isOn
knobTrailingConstraint?.isActive = isOn
}
//--------------------------------------------------
// MARK: - Initializers
//--------------------------------------------------
public override init(frame: CGRect) {
super.init(frame: frame)
setupView()
}
public convenience override init() {
self.init(frame: .zero)
}
public convenience init(isOn: Bool) {
self.init(frame: .zero)
self.isOn = isOn
}
/// - parameter isOn: Bool to set the state of the toggle.
/// - parameter didToggleAction: A closure which is executed after the toggle changes states.
public convenience init(isOn: Bool = false, didToggleAction: ActionBlock?) {
self.init(frame: .zero)
changeStateNoAnimation(isOn)
self.didToggleAction = didToggleAction
}
/// - parameter shouldToggleAction: Takes a closure that returns a boolean.
/// - parameter didToggleAction: A closure which is executed after the toggle changes states.
public convenience init(shouldToggleAction: ActionBlockConfirmation?, didToggleAction: ActionBlock?) {
self.init(frame: .zero)
self.didToggleAction = didToggleAction
self.shouldToggleAction = shouldToggleAction
}
public required init?(coder: NSCoder) {
super.init(coder: coder)
fatalError("Toggle does not support xib.")
}
//--------------------------------------------------
// MARK: - Lifecycle
//--------------------------------------------------
public override func updateView(_ size: CGFloat) {
super.updateView(size)
heightConstraint?.constant = Self.getContainerHeight()
widthConstraint?.constant = Self.getContainerWidth()
knobHeightConstraint?.constant = Self.getKnobHeight()
knobWidthConstraint?.constant = Self.getKnobWidth()
layer.cornerRadius = Self.getContainerHeight() / 2.0
knobView.layer.cornerRadius = Self.getKnobHeight() / 2.0
}
public override func setupView() {
super.setupView()
guard subviews.isEmpty else { return }
heightConstraint = heightAnchor.constraint(equalToConstant: Self.containerSize.height)
heightConstraint?.isActive = true
widthConstraint = widthAnchor.constraint(equalToConstant: Self.containerSize.width)
widthConstraint?.isActive = true
layer.cornerRadius = Self.containerSize.height / 2.0
backgroundColor = containerTintColor?.off
addSubview(knobView)
knobHeightConstraint = knobView.heightAnchor.constraint(equalToConstant: Self.knobSize.height)
knobHeightConstraint?.isActive = true
knobWidthConstraint = knobView.widthAnchor.constraint(equalToConstant: Self.knobSize.width)
knobWidthConstraint?.isActive = true
knobView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true
knobView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true
bottomAnchor.constraint(greaterThanOrEqualTo: knobView.bottomAnchor).isActive = true
knobTrailingConstraint = trailingAnchor.constraint(equalTo: knobView.trailingAnchor, constant: 1)
knobLeadingConstraint = knobView.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 1)
knobLeadingConstraint?.isActive = true
accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Toggle_buttonlabel")
}
public override func reset() {
super.reset()
backgroundColor = containerTintColor?.off
knobView.backgroundColor = knobTintColor?.off
isAnimated = false
isOn = false
constrainKnob()
didToggleAction = nil
shouldToggleAction = { return true }
}
class func getContainerWidth() -> CGFloat {
let containerWidth = Self.containerSize.width
return (MFSizeObject(standardSize: containerWidth, standardiPadPortraitSize: CGFloat(Self.containerSize.width * 1.5)))?.getValueBasedOnApplicationWidth() ?? containerWidth
}
class func getContainerHeight() -> CGFloat {
let containerHeight = Self.containerSize.height
return (MFSizeObject(standardSize: containerHeight, standardiPadPortraitSize: CGFloat(Self.containerSize.height * 1.5)))?.getValueBasedOnApplicationWidth() ?? containerHeight
}
class func getKnobWidth() -> CGFloat {
let knobWidth = Self.knobSize.width
return (MFSizeObject(standardSize: knobWidth, standardiPadPortraitSize: CGFloat(Self.knobSize.width * 1.5)))?.getValueBasedOnApplicationWidth() ?? knobWidth
}
class func getKnobHeight() -> CGFloat {
let knobHeight = Self.knobSize.width
return (MFSizeObject(standardSize: knobHeight, standardiPadPortraitSize: CGFloat(Self.knobSize.height * 1.5)))?.getValueBasedOnApplicationWidth() ?? knobHeight
}
//--------------------------------------------------
// MARK: - Actions
//--------------------------------------------------
open override func sendAction(_ action: Selector, to target: Any?, for event: UIEvent?) {
super.sendAction(action, to: target, for: event)
toggleAndAction()
}
open override func sendActions(for controlEvents: UIControl.Event) {
super.sendActions(for: controlEvents)
toggleAndAction()
}
/// This will toggle the state of the Toggle and execute the actionBlock if provided.
public func toggleAndAction() {
if let result = shouldToggleAction?(), result {
isOn.toggle()
didToggleAction?()
}
}
private func changeStateNoAnimation(_ state: Bool) {
// Hold state in case User wanted isAnimated to remain off.
let isAnimatedState = isAnimated
isAnimated = false
isOn = state
isAnimated = isAnimatedState
}
//--------------------------------------------------
// MARK: - UIResponder
//--------------------------------------------------
open override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
UIView.animate(withDuration: 0.1, animations: {
self.knobWidthConstraint?.constant += PaddingOne
self.layoutIfNeeded()
})
}
public override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
knobReformAnimation()
// Action only occurs of the user lifts up from withing acceptable region of the toggle.
guard let coordinates = touches.first?.location(in: self),
coordinates.x > -20,
coordinates.x < bounds.width + 20,
coordinates.y > -20,
coordinates.y < bounds.height + 20
else { return }
sendActions(for: .touchUpInside)
}
public func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent) {
knobReformAnimation()
sendActions(for: .touchCancel)
}
//--------------------------------------------------
// MARK: - Animations
//--------------------------------------------------
public func knobReformAnimation() {
if isAnimated {
UIView.animate(withDuration: 0.1, animations: {
self.knobWidthConstraint?.constant = Self.getKnobWidth()
self.layoutIfNeeded()
}, completion: nil)
} else {
knobWidthConstraint?.constant = Self.getKnobWidth()
layoutIfNeeded()
}
}
public override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let toggleModel = model as? ToggleModel else {
return
}
let toggleModelJSON = toggleModel.toJSON()
setWithJSON(toggleModelJSON, delegateObject: delegateObject, additionalData: additionalData)
}
}
// MARK: - Accessibility
extension Toggle {
public func formFieldGroupName() -> String? {
return json?["groupName"] as? String
}
}
// MARK: - FormValidationProtocol
extension Toggle {
public func isValidField() -> Bool {
return isOn && json?["required"] as? Bool ?? false
}
public func formFieldName() -> String? {
return json?[KeyFieldKey] as? String ?? ""
}
public func formFieldValue() -> Any? {
return NSNumber(value: isOn)
}
}
// MARK: - MVMCoreUIMoleculeViewProtocol
extension Toggle {
public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
self.delegateObject = delegateObject
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
guard let dictionary = json else { return }
if let color = dictionary["onTintColor"] as? String {
containerTintColor?.on = UIColor.mfGet(forHex: color)
}
if let color = dictionary["offTintColor"] as? String {
containerTintColor?.off = UIColor.mfGet(forHex: color)
}
if let color = dictionary["onKnobTintColor"] as? String {
knobTintColor?.on = UIColor.mfGet(forHex: color)
}
if let color = dictionary["offKnobTintColor"] as? String {
knobTintColor?.off = UIColor.mfGet(forHex: color)
}
if let state = dictionary["state"] as? Bool {
changeStateNoAnimation(state)
}
if let actionMap = dictionary.optionalDictionaryForKey("actionMap") {
didToggleAction = { MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) }
}
if let isAnimated = dictionary["isAnimated"] as? Bool {
self.isAnimated = isAnimated
}
if let isEnabled = dictionary["isEnabled"] as? Bool{
self.isEnabled = isEnabled
}
}
public class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
return Self.getContainerHeight()
}
public func needsToBeConstrained() -> Bool {
return true
}
public func alignment() -> UIStackView.Alignment {
return .trailing
}
}

View File

@ -10,32 +10,44 @@ import UIKit
public class ToggleModel: MoleculeProtocol {
public static var identifier: String = "toggle"
public var moleculeName: String?
public var backgroundColor: Color?
public var on: Bool = true
public var state: Bool = true
public var action: ActionProtocol?
public var required: Bool?
public var fieldKey: String?
enum CodingKeys: String, CodingKey {
case on
case moleculeName
case state
case action
case backgroundColor
case required
case fieldKey
}
public init(_ on: Bool) {
self.on = on
public init(_ state: Bool) {
self.state = state
}
required public init(from decoder: Decoder) throws {
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
if let on = try typeContainer.decodeIfPresent(Bool.self, forKey: .on) {
self.on = on
if let state = try typeContainer.decodeIfPresent(Bool.self, forKey: .state) {
self.state = state
}
action = try typeContainer.decodeModelIfPresent(codingKey: .action, typeCodingKey: ActionCodingKey.actionType)
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
required = try typeContainer.decodeIfPresent(Bool.self, forKey: .required)
fieldKey = try typeContainer.decodeIfPresent(String.self, forKey: .fieldKey)
}
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
try container.encodeModelIfPresent(action, forKey: .action)
try container.encode(moleculeName, forKey: .moleculeName)
try container.encodeIfPresent(state, forKey: .state)
try container.encodeIfPresent(required, forKey: .required)
try container.encodeIfPresent(fieldKey, forKey: .fieldKey)
}
}

View File

@ -81,6 +81,7 @@ extension Control: MVMCoreViewProtocol {
// MARK: - MVMCoreUIMoleculeViewProtocol
extension Control: MVMCoreUIMoleculeViewProtocol {
public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
self.json = json

View File

@ -19,6 +19,11 @@ public final class Color: Codable {
//--------------------------------------------------
public let uiColor: UIColor
public var cgColor: CGColor {
return uiColor.cgColor
}
public private(set) var hex: String = ""
public private(set) var name: String = ""

View File

@ -173,10 +173,15 @@ open class DoughnutChart: View, MVMCoreUIViewConstrainingProtocol {
return doughnutChartModel?.spaceRequired ?? true
}
func updateLabelContainer() {
labelContainer.leftPin?.constant = lineWidth()
labelContainer.topPin?.constant = lineWidth()
labelContainer.setNeedsDisplay()
}
func updateLabelContainer() {
labelContainer.setNeedsDisplay()
labelContainer.layoutIfNeeded()
let radius = sizeObject.getValueBasedOnApplicationWidth()/2 - lineWidth()
let labelheight = labelContainer.frame.height/2
let padding = sizeObject.getValueBasedOnApplicationWidth()/2 - sqrt(pow(radius, 2) - pow(labelheight, 2))
labelContainer.leftPin?.constant = padding
labelContainer.topPin?.constant = max(radius - labelheight, labelheight)
}
}

View File

@ -297,8 +297,8 @@ extension TwoButtonView {
}
}
extension TwoButtonView: MoleculeViewProtocol {
func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
extension TwoButtonView: ModelMoleculeViewProtocol {
public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let model = model as? TwoButtonViewModel else { return }
setupUI(primaryButtonShowing: model.primaryButton != nil, secondaryButtonShowing: model.secondaryButton != nil)
setDefaultCustom()

View File

@ -192,6 +192,7 @@ import UIKit
@objc public func addCaretViewAccessory() {
guard accessoryView == nil else { return }
caretView = CaretView(lineWidth: 1)
caretView?.translatesAutoresizingMaskIntoConstraints = true
caretView?.size = .small(.vertical)
caretView?.setConstraints()

View File

@ -8,9 +8,9 @@
import UIKit
@objcMembers public class LabelSwitch: ViewConstrainingView {
@objcMembers public class LabelSwitch: ViewConstrainingView, ModelMoleculeViewProtocol {
let label = Label.commonLabelB1(true)
let mvmSwitch = MVMCoreUISwitch.mvmSwitchDefault()
let mvmSwitch = Toggle()
// MARK: - MVMCoreViewProtocol
open override func updateView(_ size: CGFloat) {
@ -40,6 +40,14 @@ import UIKit
label.setWithJSON(json?.optionalDictionaryForKey("label"), delegateObject: delegateObject, additionalData: additionalData)
mvmSwitch.setWithJSON(json?.optionalDictionaryForKey("toggle"), delegateObject: delegateObject, additionalData: additionalData)
}
public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
guard let labelToggleModel = model as? LabelToggleModel else {
return
}
label.setWithModel(labelToggleModel.label, delegateObject, additionalData)
mvmSwitch.setWithModel(labelToggleModel.toggle, delegateObject, additionalData)
}
public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
return MVMCoreUISwitch.estimatedHeight(forRow: json, delegateObject: delegateObject)

View File

@ -0,0 +1,16 @@
//
// LabelToggle.swift
// MVMCoreUI
//
// Created by Suresh, Kamlesh on 1/15/20.
// Copyright © 2020 Verizon Wireless. All rights reserved.
//
import Foundation
public class LabelToggleModel: MoleculeProtocol {
public static var identifier: String = "labelToggle"
public var backgroundColor: Color?
public var label: LabelModel
public var toggle: ToggleModel
}

View File

@ -53,7 +53,7 @@
@"radioButtonLabel": RadioButtonLabel.class,
@"listItem": MoleculeTableViewCell.class,
@"accordionListItem": AccordionMoleculeTableViewCell.class,
@"toggle": MVMCoreUISwitch.class,
@"toggle": Toggle.class,
@"leftRightLabelView": LeftRightLabelView.class,
@"actionDetailWithImage": ActionDetailWithImage.class,
@"image": MFLoadImageView.class,

View File

@ -12,6 +12,7 @@ import Foundation
public static func registerObjects() {
ModelRegistry.register(LabelModel.self)
ModelRegistry.register(HeaderModel.self)
ModelRegistry.register(FooterModel.self)
ModelRegistry.register(HeadlineBodyModel.self)
ModelRegistry.register(MoleculeStackModel.self)
ModelRegistry.register(StackItemModel.self)
@ -52,6 +53,7 @@ import Foundation
ModelRegistry.register(LeftRightLabelModel.self)
ModelRegistry.register(CaretViewModel.self)
ModelRegistry.register(CaretLinkModel.self)
ModelRegistry.register(LabelToggleModel.self)
ModelRegistry.register(DoughnutChartModel.self)
}
}