diff --git a/MVMCoreUI/Atoms/Views/Switch.swift b/MVMCoreUI/Atoms/Views/Switch.swift index 025c7b64..03724267 100644 --- a/MVMCoreUI/Atoms/Views/Switch.swift +++ b/MVMCoreUI/Atoms/Views/Switch.swift @@ -16,9 +16,10 @@ public typealias ValueChangeBlock = () -> () //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - - public var trackTintColor: (on: UIColor?, off: UIColor?)? - public var thumbTintColor: (on: UIColor?, off: UIColor?)? + + public var trackTintColor: (on: UIColor?, off: UIColor?)? = (on: .mfShamrock(), off: .black) + public var thumbTintColor: (on: UIColor?, off: UIColor?)? = (on: .white, off: .white) + public var disabledTintColor: (track: UIColor?, thumb: UIColor?)? = (track: .mfSilver(), thumb: .white) var shouldTouchToSwitch = false var valueChangedBlock: ValueChangeBlock? @@ -40,21 +41,16 @@ public typealias ValueChangeBlock = () -> () open override var isEnabled: Bool { didSet { - if isEnabled { - - } else { - - } + isUserInteractionEnabled = isEnabled + backgroundColor = isEnabled ? trackTintColor?.on : disabledTintColor?.track + thumbView.backgroundColor = isEnabled ? thumbTintColor?.on : disabledTintColor?.thumb } } open var isOn: Bool = false { didSet { - if isOn { - - } else { - - } + backgroundColor = isOn ? trackTintColor?.on : trackTintColor?.off + thumbView.backgroundColor = isOn ? thumbTintColor?.on : thumbTintColor?.off } } @@ -62,7 +58,7 @@ public typealias ValueChangeBlock = () -> () // MARK: - Delegate //-------------------------------------------------- - private var delegate: DelegateObject? + private var delegateObject: MVMCoreUIDelegateObject? //-------------------------------------------------- // MARK: - Constraints @@ -85,17 +81,17 @@ public typealias ValueChangeBlock = () -> () } public convenience override init() { - self.init(frame: frame) + self.init(frame: .zero) } public convenience init(isOn: Bool, changeBlock: ValueChangeBlock?) { - self.init(frame: frame) + self.init(frame: .zero) self.isOn = isOn valueChangedBlock = changeBlock } public convenience init(changeBlock: ValueChangeBlock?) { - self.init(frame: frame) + self.init(frame: .zero) valueChangedBlock = changeBlock } @@ -126,12 +122,6 @@ public typealias ValueChangeBlock = () -> () guard !subviews.isEmpty else { return } - trackTintColor?.on = .mfSwitchOnTint() // Green - trackTintColor?.off = .mfSwitchOffTint() // Black - - thumbTintColor?.on = .white - thumbTintColor?.off = .white - canChangeValue = true shouldTouchToSwitch = true valueShouldChange = true @@ -165,6 +155,22 @@ public typealias ValueChangeBlock = () -> () accessibilityLabel = MVMCoreUIUtility.hardcodedString(withKey: "Switch_buttonlabel") } + class func getTrackWidth() -> CGFloat { + return (MFSizeObject(standardSize: Switch.trackSize.width, standardiPadPortraitSize: CGFloat(Switch.trackSize.width * 1.5)))!.getValueBasedOnApplicationWidth() + } + + class func getTrackHeight() -> CGFloat { + return (MFSizeObject(standardSize: Switch.trackSize.height, standardiPadPortraitSize: CGFloat(Switch.trackSize.height * 1.5) ))!.getValueBasedOnApplicationWidth() + } + + class func getThumbWidth() -> CGFloat { + return (MFSizeObject(standardSize: Switch.thumbSize.width, standardiPadPortraitSize: CGFloat(Switch.thumbSize.width * 1.5)))!.getValueBasedOnApplicationWidth() + } + + class func getThumbHeight() -> CGFloat { + return (MFSizeObject(standardSize: Switch.thumbSize.height, standardiPadPortraitSize: CGFloat(Switch.thumbSize.height * 1.5)))!.getValueBasedOnApplicationWidth() + } + //-------------------------------------------------- // MARK: - Methods //-------------------------------------------------- @@ -174,11 +180,64 @@ public typealias ValueChangeBlock = () -> () actionBlock?() } + public func setState(_ state: Bool, animated: Bool) { + + setState(state, withoutBlockAnimated: animated) + valueChangedBlock?() + FormValidator.enableByValidationWith(delegate: delegateObject?.formValidationProtocol) + } + + public func setState(_ state: Bool, withoutBlockAnimated animated: Bool) { + + isOn = state + + if !shouldTouchToSwitch { + thumbEnlargeAnimation() + thumbMoveAnitmationTo(on: isOn) + thumbShakeAnitmationTo(on: isOn) + } + + if isOn { + thumbLeadingConstraint?.priority = UILayoutPriority(1) + thumbTrailingConstraint?.priority = UILayoutPriority(999) + thumbTrailingConstraint?.constant = 1 + + } else { + thumbTrailingConstraint?.priority = UILayoutPriority(1) + thumbLeadingConstraint?.priority = UILayoutPriority(999) + thumbLeadingConstraint?.constant = 1 + } + + setBaseColorToOn(isOn, animated: animated) + thumbReformAnimation(animated) + accessibilityValue = state ? MVMCoreUIUtility.hardcodedString(withKey: "AccOn") : MVMCoreUIUtility.hardcodedString(withKey: "AccOff") + setNeedsLayout() + layoutIfNeeded() + } + + @discardableResult + public func changeValue() -> Bool { + + isOn.toggle() + shouldTouchToSwitch = false + setState(isOn, animated: true) + shouldTouchToSwitch = true + sendActions(for: .valueChanged) + + return isOn + } //-------------------------------------------------- // MARK: - UIResponder //-------------------------------------------------- + override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool { + + let faultTolerance: CGFloat = 20.0 + let area = bounds.insetBy(dx: -faultTolerance, dy: -faultTolerance) + return area.contains(point) + } + public func touchesBegan(_ touches: Set, with event: UIEvent) { thumbEnlargeAnimation() @@ -198,6 +257,11 @@ public typealias ValueChangeBlock = () -> () valueShouldChange = true } + open override func touchesEnded(_ touches: Set, with event: UIEvent?) { + + sendActions(for: .touchUpInside) + } + public func touchesMoved(_ touches: Set, with event: UIEvent) { if shouldTouchToSwitch { @@ -211,7 +275,7 @@ public typealias ValueChangeBlock = () -> () thumbReformAnimation(true) } } - + /* if touchIsOutSide(touches) { sendActions(for: .touchDragOutside) if !shouldTouchToSwitch { @@ -220,6 +284,14 @@ public typealias ValueChangeBlock = () -> () } else { sendActions(for: .touchDragInside) } + */ + } + + func touchMoves(toLeft touches: Set?) -> Bool { + + let location = touches?.first?.location(in: self) + let x = CGFloat(location?.x ?? 0.0) + return x < frame.size.width / 2.0 } public func touchesCancelled(_ touches: Set, with event: UIEvent) { @@ -232,7 +304,10 @@ public typealias ValueChangeBlock = () -> () sendActions(for: .touchCancel) } - // MARK: - animation + //-------------------------------------------------- + // MARK: - Animation + //-------------------------------------------------- + public func thumbEnlargeAnimation() { UIView.animate(withDuration: 0.1, animations: { @@ -247,7 +322,7 @@ public typealias ValueChangeBlock = () -> () UIView.animate(withDuration: 0.1, animations: { self.thumbWidthConstraint?.constant = Switch.getThumbWidth() self.layoutIfNeeded() - }) { finished in } + }, completion: nil) } else { thumbWidthConstraint?.constant = Switch.getThumbWidth() layoutIfNeeded() @@ -285,6 +360,7 @@ public typealias ValueChangeBlock = () -> () if toOn { thumbView.backgroundColor = thumbTintColor?.on backgroundColor = trackTintColor?.on + } else { thumbView.backgroundColor = thumbTintColor?.off backgroundColor = trackTintColor?.off @@ -310,7 +386,9 @@ public typealias ValueChangeBlock = () -> () } else { self.thumbLeadingConstraint?.constant = Switch.shakeIntensity } + self.layoutIfNeeded() + }, completion: nil) UIView.animate(withDuration: 0.2, delay: 0.1, options: [], animations: { @@ -319,96 +397,13 @@ public typealias ValueChangeBlock = () -> () } else { self.thumbLeadingConstraint?.constant = 1 } + self.layoutIfNeeded() + }) { finished in self.valueShouldChange = true } } - - public func setState(_ state: Bool, animated: Bool) { - setState(state, withoutBlockAnimated: animated) - - valueChangedBlock?() - - // if delegate && delegate.responds(to: #selector(formValidationProtocol)) && delegate.perform(#selector(formValidationProtocol)).responds(to: #selector(Unmanaged.formValidatorModel)) { - let formValidator = delegate.perform(#selector(formValidationProtocol)).perform(#selector(Unmanaged.formValidatorModel)) as? FormValidator - formValidator?.enableByValidation() - // } - } - - public func setState(_ state: Bool, withoutBlockAnimated animated: Bool) { - - isOn = state - - if !shouldTouchToSwitch { - thumbEnlargeAnimation() - thumbMoveAnitmationTo(on: isOn) - thumbShakeAnitmationTo(on: isOn) - } - - if isOn { - thumbLeadingConstraint?.priority = UILayoutPriority(1) - thumbTrailingConstraint?.priority = UILayoutPriority(999) - thumbTrailingConstraint?.constant = 1 - } else { - thumbTrailingConstraint?.priority = UILayoutPriority(1) - thumbLeadingConstraint?.priority = UILayoutPriority(999) - thumbLeadingConstraint?.constant = 1 - } - - setBaseColorToOn(isOn, animated: animated) - thumbReformAnimation(animated) - accessibilityValue = state ? MVMCoreUIUtility.hardcodedString(withKey: "AccOn") : MVMCoreUIUtility.hardcodedString(withKey: "AccOff") - setNeedsLayout() - layoutIfNeeded() - } - - @discardableResult - public func changeValue() -> Bool { - - isOn.toggle() - shouldTouchToSwitch = false - setState(isOn, animated: true) - shouldTouchToSwitch = true - sendActions(for: .valueChanged) - - return isOn - } - - func touchMoves(toLeft touches: Set?) -> Bool { - - let location = touches?.first?.location(in: self) - let x = CGFloat(location?.x ?? 0.0) - return x < frame.size.width / 2.0 - } - - override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool { - - let faultTolerance: CGFloat = 20.0 - let area = bounds.insetBy(dx: -faultTolerance, dy: -faultTolerance) - return area.contains(point) - } - - open override func touchesEnded(_ touches: Set, with event: UIEvent?) { - - sendActions(for: .touchUpInside) - } - - class func getTrackWidth() -> CGFloat { - return (MFSizeObject(standardSize: Switch.trackSize.width, standardiPadPortraitSize: CGFloat(Switch.trackSize.width * 1.5)))!.getValueBasedOnApplicationWidth() - } - - class func getTrackHeight() -> CGFloat { - return (MFSizeObject(standardSize: Switch.trackSize.height, standardiPadPortraitSize: CGFloat(Switch.trackSize.height * 1.5) ))!.getValueBasedOnApplicationWidth() - } - - class func getThumbWidth() -> CGFloat { - return (MFSizeObject(standardSize: Switch.thumbSize.width, standardiPadPortraitSize: CGFloat(Switch.thumbSize.width * 1.5)))!.getValueBasedOnApplicationWidth() - } - - class func getThumbHeight() -> CGFloat { - return (MFSizeObject(standardSize: Switch.thumbSize.height, standardiPadPortraitSize: CGFloat(Switch.thumbSize.height * 1.5)))!.getValueBasedOnApplicationWidth() - } } // MARK: - Accessibility @@ -438,9 +433,9 @@ extension Switch { // MARK: - MVMCoreUIMoleculeViewProtocol extension Switch { - public override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { - self.json = json - delegate = delegateObject + public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + self.delegateObject = delegateObject guard let dictionary = json else { return } @@ -454,11 +449,11 @@ extension Switch { trackTintColor?.off = UIColor.mfGet(forHex: color) } - if let color = dictionary["onthumbTintColor"] as? String { + if let color = dictionary["onThumbTintColor"] as? String { thumbTintColor?.on = UIColor.mfGet(forHex: color) } - if let color = dictionary["offthumbTintColor"] as? String { + if let color = dictionary["offThumbTintColor"] as? String { thumbTintColor?.off = UIColor.mfGet(forHex: color) }