merge
This commit is contained in:
commit
47ccd681ae
@ -81,6 +81,7 @@
|
|||||||
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; };
|
0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A6BF4712360C56C0028F841 /* BaseDropdownEntryField.swift */; };
|
||||||
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
|
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
|
||||||
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.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 */; };
|
0ABD136B237B193A0081388D /* EntryFieldContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136A237B193A0081388D /* EntryFieldContainer.swift */; };
|
||||||
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; };
|
0ABD136D237CAD1E0081388D /* DateDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD136C237CAD1E0081388D /* DateDropdownEntryField.swift */; };
|
||||||
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; };
|
0ABD1371237DB0450081388D /* ItemDropdownEntryField.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0ABD1370237DB0450081388D /* ItemDropdownEntryField.swift */; };
|
||||||
@ -352,6 +353,7 @@
|
|||||||
0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = "<group>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
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>"; };
|
0ABD136A237B193A0081388D /* EntryFieldContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EntryFieldContainer.swift; sourceTree = "<group>"; };
|
||||||
@ -1104,6 +1106,7 @@
|
|||||||
D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */,
|
D28A838223CCBD3F00DFE4FC /* CircleProgressModel.swift */,
|
||||||
943784F3236B77BB006A1E82 /* GraphView.swift */,
|
943784F3236B77BB006A1E82 /* GraphView.swift */,
|
||||||
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */,
|
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */,
|
||||||
|
0AA33B392398524F0067DD0F /* Toggle.swift */,
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1426,6 +1429,7 @@
|
|||||||
D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */,
|
D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */,
|
||||||
D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */,
|
D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */,
|
||||||
D2B18B7F2360913400A9AEDC /* Control.swift in Sources */,
|
D2B18B7F2360913400A9AEDC /* Control.swift in Sources */,
|
||||||
|
0AA33B3A2398524F0067DD0F /* Toggle.swift in Sources */,
|
||||||
D29DF12F21E6851E003B2FB9 /* MVMCoreUITopAlertMainView.m in Sources */,
|
D29DF12F21E6851E003B2FB9 /* MVMCoreUITopAlertMainView.m in Sources */,
|
||||||
012A88C8238DB02000FE3DA1 /* ModelMoleculeDelegateProtocol.swift in Sources */,
|
012A88C8238DB02000FE3DA1 /* ModelMoleculeDelegateProtocol.swift in Sources */,
|
||||||
DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */,
|
DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */,
|
||||||
|
|||||||
416
MVMCoreUI/Atoms/Views/Toggle.swift
Normal file
416
MVMCoreUI/Atoms/Views/Toggle.swift
Normal file
@ -0,0 +1,416 @@
|
|||||||
|
//
|
||||||
|
// 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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -81,6 +81,7 @@ extension Control: MVMCoreViewProtocol {
|
|||||||
|
|
||||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||||
extension Control: MVMCoreUIMoleculeViewProtocol {
|
extension Control: MVMCoreUIMoleculeViewProtocol {
|
||||||
|
|
||||||
public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||||
self.json = json
|
self.json = json
|
||||||
|
|
||||||
|
|||||||
@ -53,7 +53,7 @@
|
|||||||
@"radioButtonLabel": RadioButtonLabel.class,
|
@"radioButtonLabel": RadioButtonLabel.class,
|
||||||
@"listItem": MoleculeTableViewCell.class,
|
@"listItem": MoleculeTableViewCell.class,
|
||||||
@"accordionListItem": AccordionMoleculeTableViewCell.class,
|
@"accordionListItem": AccordionMoleculeTableViewCell.class,
|
||||||
@"toggle": MVMCoreUISwitch.class,
|
@"toggle": Toggle.class,
|
||||||
@"leftRightLabelView": LeftRightLabelView.class,
|
@"leftRightLabelView": LeftRightLabelView.class,
|
||||||
@"actionDetailWithImage": ActionDetailWithImage.class,
|
@"actionDetailWithImage": ActionDetailWithImage.class,
|
||||||
@"image": MFLoadImageView.class,
|
@"image": MFLoadImageView.class,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user