diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 973b16c3..9eeece24 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -53,6 +53,7 @@ 9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; }; 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; }; C07065C42395677300FBF997 /* Link.swift in Sources */ = {isa = PBXBuildFile; fileRef = C07065C32395677300FBF997 /* Link.swift */; }; + C003506123AA94CD00B6AC29 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = C003506023AA94CD00B6AC29 /* Button.swift */; }; C7192E7D23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = C7192E7C23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; D213347723843825008E41B3 /* Line.swift in Sources */ = {isa = PBXBuildFile; fileRef = D213347623843825008E41B3 /* Line.swift */; }; @@ -254,6 +255,7 @@ 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = ""; }; 948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = ""; }; C07065C32395677300FBF997 /* Link.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Link.swift; sourceTree = ""; }; + C003506023AA94CD00B6AC29 /* Button.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Button.swift; sourceTree = ""; }; C7192E7C23C301750050C2A0 /* HeadLineBodyCaretLinkImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadLineBodyCaretLinkImage.swift; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; D213347623843825008E41B3 /* Line.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Line.swift; sourceTree = ""; }; @@ -955,6 +957,7 @@ D2B18B7D236090D500A9AEDC /* BaseClasses */ = { isa = PBXGroup; children = ( + C003506023AA94CD00B6AC29 /* Button.swift */, D2B18B7E2360913400A9AEDC /* Control.swift */, D2B18B802360945C00A9AEDC /* View.swift */, 0AE14F63238315D2005417F8 /* TextField.swift */, @@ -1228,6 +1231,8 @@ D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */, D29DF26C21E6AA0B003B2FB9 /* FLAnimatedImage.m in Sources */, D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */, + C003506123AA94CD00B6AC29 /* Button.swift in Sources */, + D29DF25121E6A177003B2FB9 /* MFDigitTextBox.m in Sources */, DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */, 0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */, 0A6BF4722360C56C0028F841 /* BaseDropdownEntryField.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/CaretButton.swift b/MVMCoreUI/Atoms/Buttons/CaretButton.swift index 7ffd8749..887c4c5f 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretButton.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretButton.swift @@ -44,10 +44,8 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI super.layoutSubviews() } - public func setEnabled(_ enabled: Bool) { - super.isEnabled = enabled - - changeCaretColor() + override public var isEnabled: Bool { + didSet { changeCaretColor() } } public func updateView(_ size: CGFloat) { } @@ -84,7 +82,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI caretView.widthAnchor.constraint(equalToConstant: width).isActive = true caretView.heightAnchor.constraint(equalToConstant: height).isActive = true - let caretLabelSpacing = NSLayoutConstraint(item: caretView, attribute: .left, relatedBy: .equal, toItem: titleLabel, attribute: .right, multiplier: 1.0, constant: 4.0) + let caretLabelSpacing = NSLayoutConstraint(item: caretView, attribute: .left, relatedBy: .equal, toItem: titleLabel, attribute: .right, multiplier: 1.0, constant: 4) caretLabelSpacing.isActive = true caretSpacingConstraint = caretLabelSpacing @@ -118,6 +116,14 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI guard let dictionary = json else { return } + if let title = dictionary.optionalStringForKey(KeyTitle) { + setTitle(title, for: .normal) + } + + if let disableButtonAsAny = dictionary[KeyDisableButton], let isDisabled = disableButtonAsAny as? Bool { + isEnabled = !isDisabled + } + if let backgroundColorHex = dictionary[KeyBackgroundColor] as? String { backgroundColor = UIColor.mfGet(forHex: backgroundColorHex) } diff --git a/MVMCoreUI/Atoms/Views/DashLine.swift b/MVMCoreUI/Atoms/Views/DashLine.swift index edd911e0..c66d68b7 100644 --- a/MVMCoreUI/Atoms/Views/DashLine.swift +++ b/MVMCoreUI/Atoms/Views/DashLine.swift @@ -31,7 +31,6 @@ open class DashLine: View { required public init?(coder: NSCoder) { super.init(coder: coder) - fatalError("DashLine xib not supported") } //------------------------------------------------------ diff --git a/MVMCoreUI/BaseClasses/Button.swift b/MVMCoreUI/BaseClasses/Button.swift new file mode 100644 index 00000000..1d5d743e --- /dev/null +++ b/MVMCoreUI/BaseClasses/Button.swift @@ -0,0 +1,133 @@ +// +// Button.swift +// MVMCoreUI +// +// Created by Robinson, Blake on 12/18/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +public typealias ButtonBlock = (Button) -> () + + +@objcMembers open class Button: UIButton, MFButtonProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public var json: [AnyHashable: Any]? + public var actionMap: [AnyHashable: Any]? + + private var initialSetupPerformed = false + + private var buttonBlock: ButtonBlock? + + //-------------------------------------------------- + // MARK: - Delegate + //-------------------------------------------------- + + public weak var buttonDelegate: ButtonDelegateProtocol? + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + + public override init(frame: CGRect) { + super.init(frame: .zero) + initialSetup() + } + + public convenience init() { + self.init(frame: .zero) + initialSetup() + } + + public required init?(coder: NSCoder) { + super.init(coder: coder) + fatalError("Button does not support xib.") + } + + //-------------------------------------------------- + // MARK: - Setup + //-------------------------------------------------- + + public func initialSetup() { + + if !initialSetupPerformed { + initialSetupPerformed = true + setupView() + } + } + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + + public func addBlock( event: Event, _ buttonBlock: @escaping ButtonBlock) { + self.buttonBlock = buttonBlock + addTarget(self, action: #selector(callBlock(_:)), for: event) + } + + func callBlock(_ sender: Button) { + buttonBlock?(self) + } + + public func setWithActionMap(_ actionMap: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + self.actionMap = actionMap + + buttonDelegate = delegateObject?.buttonDelegate + + addBlock(event: .touchUpInside) { [weak self] sender in + guard let self = self else { return } + + if self.buttonDelegate?.button?(self, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? true { + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject) + } + } + } +} + +// MARK: - MVMCoreUIMoleculeViewProtocol +extension Button: MVMCoreUIMoleculeViewProtocol { + + public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + self.json = json + + guard let dictionary = json else { return } + + if let backgroundColorString = dictionary[KeyBackgroundColor] as? String { + backgroundColor = UIColor.mfGet(forHex: backgroundColorString) + } + + if let title = dictionary[KeyTitle] as? String { + setTitle(title, for: .normal) + } + } + + public func reset() { + backgroundColor = .clear + } +} + + +// MARK: - MVMCoreViewProtocol +extension Button: MVMCoreViewProtocol { + + public func updateView(_ size: CGFloat) {} + + /// Will be called only once. + public func setupView() { + + translatesAutoresizingMaskIntoConstraints = false + insetsLayoutMarginsFromSafeArea = false + titleLabel?.numberOfLines = 0 + titleLabel?.lineBreakMode = .byWordWrapping + } +} + +// MARK: AppleGuidelinesProtocol +extension Button: AppleGuidelinesProtocol { + + override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool { + return Self.acceptablyOutsideBounds(point: point, bounds: bounds) + } +}