diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index a222046d..b406d4f2 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -11,6 +11,7 @@ 01DF567021FA5AB300CC099B /* TextFieldListFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */; }; D206997721FB8A0B00CAE0DE /* MVMCoreUINavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; }; D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = D206997621FB8A0B00CAE0DE /* MVMCoreUINavigationController.m */; }; + D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; D22D1F1A220341F60077CEC0 /* MVMCoreUICheckBox.h in Headers */ = {isa = PBXBuildFile; fileRef = D22D1F18220341F50077CEC0 /* MVMCoreUICheckBox.h */; settings = {ATTRIBUTES = (Public, ); }; }; D22D1F1B220341F60077CEC0 /* MVMCoreUICheckBox.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F19220341F50077CEC0 /* MVMCoreUICheckBox.m */; }; D22D1F1E220343560077CEC0 /* MVMCoreUICheckMarkView.h in Headers */ = {isa = PBXBuildFile; fileRef = D22D1F1C220343560077CEC0 /* MVMCoreUICheckMarkView.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -22,6 +23,7 @@ D274CA332236A78900B01B62 /* StandardFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274CA322236A78900B01B62 /* StandardFooterView.swift */; }; D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */; }; D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */; }; + D282AACB2243C61700C46919 /* ButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AACA2243C61700C46919 /* ButtonView.swift */; }; D28B4F8A21FF967C00712C7A /* MVMCoreUIObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */; }; D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */; }; @@ -30,7 +32,6 @@ D29770F321F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770EF21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29770F421F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770F021F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29770F521F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770F121F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m */; }; - D29770F821F7C73800B2F0D0 /* PrimaryButtonView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770F621F7C73800B2F0D0 /* PrimaryButtonView.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29770F921F7C73800B2F0D0 /* PrimaryButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770F721F7C73800B2F0D0 /* PrimaryButtonView.m */; }; D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770FA21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m */; }; D29770FD21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770FB21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -165,6 +166,7 @@ 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldListFormViewController.swift; sourceTree = ""; }; D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUINavigationController.h; sourceTree = ""; }; D206997621FB8A0B00CAE0DE /* MVMCoreUINavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUINavigationController.m; sourceTree = ""; }; + D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; D22D1F18220341F50077CEC0 /* MVMCoreUICheckBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUICheckBox.h; sourceTree = ""; }; D22D1F19220341F50077CEC0 /* MVMCoreUICheckBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUICheckBox.m; sourceTree = ""; }; D22D1F1C220343560077CEC0 /* MVMCoreUICheckMarkView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUICheckMarkView.h; sourceTree = ""; }; @@ -176,6 +178,7 @@ D274CA322236A78900B01B62 /* StandardFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardFooterView.swift; sourceTree = ""; }; D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFLoadImageView.swift; sourceTree = ""; }; D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFTransparentGIFView.swift; sourceTree = ""; }; + D282AACA2243C61700C46919 /* ButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonView.swift; sourceTree = ""; }; D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIObject.h; sourceTree = ""; }; D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIObject.m; sourceTree = ""; }; D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsView.m; sourceTree = ""; }; @@ -417,6 +420,8 @@ 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */, D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */, D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */, + D282AACA2243C61700C46919 /* ButtonView.swift */, + D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */, D29770F621F7C73800B2F0D0 /* PrimaryButtonView.h */, D29770F721F7C73800B2F0D0 /* PrimaryButtonView.m */, D2A514662213885800345BFB /* StandardHeaderView.swift */, @@ -746,7 +751,6 @@ D2A5145D2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h in Headers */, D28B4F8A21FF967C00712C7A /* MVMCoreUIObject.h in Headers */, D29DF2CA21E7BFC8003B2FB9 /* MFSizeThreshold.h in Headers */, - D29770F821F7C73800B2F0D0 /* PrimaryButtonView.h in Headers */, D29DF28021E7AA51003B2FB9 /* MVMCoreUIDetailViewProtocol.h in Headers */, D29DF2BD21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.h in Headers */, D29DF2EE21ECEADF003B2FB9 /* MFFonts.h in Headers */, @@ -877,6 +881,7 @@ D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */, D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */, D29DF2EF21ECEAE1003B2FB9 /* MFFonts.m in Sources */, + D282AACB2243C61700C46919 /* ButtonView.swift in Sources */, D29DF2AE21E7B3A4003B2FB9 /* MFTextView.m in Sources */, D29DF18121E69E50003B2FB9 /* MFView.m in Sources */, D29DF18321E69E54003B2FB9 /* SeparatorView.m in Sources */, @@ -901,6 +906,7 @@ D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */, D29DF29821E7ADB8003B2FB9 /* MFScrollingViewController.m in Sources */, D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */, + D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */, D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */, D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */, D29DF17821E69E1F003B2FB9 /* MFCaretButton.m in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/PrimaryButton.h b/MVMCoreUI/Atoms/Buttons/PrimaryButton.h index 182a527b..fb93c33a 100644 --- a/MVMCoreUI/Atoms/Buttons/PrimaryButton.h +++ b/MVMCoreUI/Atoms/Buttons/PrimaryButton.h @@ -51,7 +51,7 @@ static CGFloat const PrimaryButtonSmallHeight = 30.0; + (nullable instancetype)primarySmallButton:(BOOL)enabled; + (nullable instancetype)primaryTinyButton:(BOOL)enabled; -+ (nullable instancetype)primaryButton; ++ (nonnull instancetype)primaryButton NS_SWIFT_NAME(button()); + (nullable instancetype)primarySmallButton; + (nullable instancetype)primaryWhiteButton:(BOOL)small; diff --git a/MVMCoreUI/Atoms/Buttons/PrimaryButton.m b/MVMCoreUI/Atoms/Buttons/PrimaryButton.m index 960e29e7..a13a693c 100644 --- a/MVMCoreUI/Atoms/Buttons/PrimaryButton.m +++ b/MVMCoreUI/Atoms/Buttons/PrimaryButton.m @@ -547,7 +547,7 @@ return button; } -+ (nullable instancetype)primaryButton { ++ (nonnull instancetype)primaryButton { PrimaryButton *button = [self getButton]; button.primaryButtonType = PrimaryButtonTypeBlack; [button setAsBlack]; diff --git a/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsTableViewController.m b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsTableViewController.m index e68fda0f..7a16405b 100644 --- a/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsTableViewController.m +++ b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsTableViewController.m @@ -7,7 +7,6 @@ // #import "TopLabelsAndBottomButtonsTableViewController.h" -#import #import #import #import @@ -18,6 +17,7 @@ #import #import #import +#import @import MVMAnimationFramework; @@ -117,7 +117,7 @@ // Sets up the buttons/button. NSDictionary *primaryButtonDictionary = [self primaryButtonMap]; NSDictionary *secondaryButtonDictionary = [self secondaryButtonMap]; - PrimaryButtonView *buttonView = [[PrimaryButtonView alloc] initWithPrimaryButtonMap:primaryButtonDictionary secondaryButtonMap:secondaryButtonDictionary actionDelegate:self additionalData:nil buttonDelegate:self]; + TwoButtonView *buttonView = [[TwoButtonView alloc] initWithPrimaryButtonMap:primaryButtonDictionary secondaryButtonMap:secondaryButtonDictionary actionDelegate:self additionalData:nil buttonDelegate:self]; self.secondaryButton = buttonView.secondaryButton; self.primaryButton = buttonView.primaryButton; @@ -430,8 +430,8 @@ - (void)setPrimaryLeftButtonHidden:(BOOL)left rightButtonHidden:(BOOL)right { - if ([self.bottomView isKindOfClass:[PrimaryButtonView class]]) { - PrimaryButtonView *buttonView = (PrimaryButtonView *)self.bottomView; + if ([self.bottomView isKindOfClass:[TwoButtonView class]]) { + TwoButtonView *buttonView = (TwoButtonView *)self.bottomView; if (right && !left) { [buttonView hidePrimaryRightButton]; } else if (!right && left) { diff --git a/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.m b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.m index 4d2bc3c6..be14e149 100644 --- a/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.m +++ b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.m @@ -7,7 +7,6 @@ // #import "TopLabelsAndBottomButtonsViewController.h" -#import #import #import #import @@ -18,6 +17,7 @@ #import #import #import +#import @import MVMAnimationFramework; @@ -80,18 +80,18 @@ } if (!self.customBottemView) { - PrimaryButtonView *buttonView = (PrimaryButtonView *)self.bottomView; + TwoButtonView *buttonView = (TwoButtonView *)self.bottomView; if (self.secondaryButton || self.primaryButton) { UIEdgeInsets paddingForBottomButtons = [self paddingForBottomButtons]; - buttonView.leftPin.constant = paddingForBottomButtons.left; - buttonView.rightPin.constant = paddingForBottomButtons.right; + [buttonView setLeftPinConstant:paddingForBottomButtons.left]; + [buttonView setRightPinConstant:paddingForBottomButtons.right]; buttonView.topPin.constant = paddingForBottomButtons.top; buttonView.bottomPin.constant = paddingForBottomButtons.bottom; } else { buttonView.topPin.constant = 0; buttonView.bottomPin.constant = 0; - buttonView.leftPin.constant = 0; - buttonView.rightPin.constant = 0; + [buttonView setLeftPinConstant:0]; + [buttonView setRightPinConstant:0]; } } } @@ -127,7 +127,7 @@ // Sets up the buttons/button. NSDictionary *primaryButtonDictionary = [self primaryButtonMap]; NSDictionary *secondaryButtonDictionary = [self secondaryButtonMap]; - PrimaryButtonView *buttonView = [[PrimaryButtonView alloc] initWithPrimaryButtonMap:primaryButtonDictionary secondaryButtonMap:secondaryButtonDictionary actionDelegate:self additionalData:nil buttonDelegate:self]; + TwoButtonView *buttonView = [[TwoButtonView alloc] initWithPrimaryButtonMap:primaryButtonDictionary secondaryButtonMap:secondaryButtonDictionary actionDelegate:self additionalData:nil buttonDelegate:self]; self.secondaryButton = buttonView.secondaryButton; self.primaryButton = buttonView.primaryButton; bottomView = buttonView; diff --git a/MVMCoreUI/MVMCoreUI.h b/MVMCoreUI/MVMCoreUI.h index 3a8029c4..96f585d0 100644 --- a/MVMCoreUI/MVMCoreUI.h +++ b/MVMCoreUI/MVMCoreUI.h @@ -109,7 +109,6 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[]; #pragma mark - Molecules #import -#import #import #pragma mark - Templates diff --git a/MVMCoreUI/Molecules/ButtonView.swift b/MVMCoreUI/Molecules/ButtonView.swift new file mode 100644 index 00000000..04be7ba5 --- /dev/null +++ b/MVMCoreUI/Molecules/ButtonView.swift @@ -0,0 +1,135 @@ +// +// ButtonView.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 3/21/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers open class ButtonView: ViewConstrainingView { + open var primaryButton: PrimaryButton? = PrimaryButton.button() + open var alignCenterPin: NSLayoutConstraint? + open var alignCenterLeftPin: NSLayoutConstraint? + open var alignCenterRightPin: NSLayoutConstraint? + + // 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 convenience init(buttonSmall small: Bool, enabled: Bool) { + self.init() + primaryButton?.setAsSmall(small) + primaryButton?.isEnabled = enabled + } + + public init(withJSON json: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate: NSObject?, buttonDelegate: Any?) { + super.init(frame: .zero) + setWithJSON(json, delegate: actionDelegate, additionalData: additionalData) + } + + // MARK: - MVMCoreViewProtocol + open override func updateView(_ size: CGFloat) { + super.updateView(size) + MVMCoreDispatchUtility.performBlock(onMainThread: { + self.primaryButton?.updateView(size) + }) + } + + open override func setupView() { + super.setupView() + setupButton() + alignCenter() + } + + // MARK: - MVMCoreUIMoleculeViewProtocol + open override func setAsMolecule() { + super.setAsMolecule() + primaryButton?.setAsMolecule() + } + + open override func setWithJSON(_ json: [AnyHashable : Any]?, delegate: NSObject?, additionalData: [AnyHashable : Any]?) { + super.setWithJSON(json, delegate: delegate, additionalData: additionalData) + primaryButton?.setWithJSON(json, delegate: delegate, additionalData: additionalData) + } + + // MARK: - Constraining + func setupButton() { + if let primaryButton = primaryButton, !subviews.contains(primaryButton) { + addSubview(primaryButton) + setupConstraints(forView: primaryButton) + } + } + + func setupConstraints(forView view: UIView) { + leftPin = view.leftAnchor.constraint(equalTo: leftAnchor) + topPin = view.topAnchor.constraint(equalTo: topAnchor) + rightPin = rightAnchor.constraint(equalTo: view.rightAnchor) + bottomPin = bottomAnchor.constraint(equalTo: view.bottomAnchor) + leftPin?.isActive = true + topPin?.isActive = true + rightPin?.isActive = true + bottomPin?.isActive = true + + alignCenterPin = view.centerXAnchor.constraint(equalTo: centerXAnchor) + alignCenterLeftPin = view.leftAnchor.constraint(greaterThanOrEqualTo: leftAnchor) + alignCenterRightPin = rightAnchor.constraint(greaterThanOrEqualTo: view.rightAnchor) + } + + open func alignLeft() { + alignCenterPin?.isActive = false + alignCenterLeftPin?.isActive = false + alignCenterRightPin?.isActive = true + leftPin?.isActive = true + rightPin?.isActive = false + } + + open func alignCenter() { + alignCenterPin?.isActive = true + alignCenterLeftPin?.isActive = true + alignCenterRightPin?.isActive = true + leftPin?.isActive = false + rightPin?.isActive = false + } + + open func alignFill() { + alignCenterPin?.isActive = false + alignCenterLeftPin?.isActive = false + alignCenterRightPin?.isActive = false + leftPin?.isActive = true + rightPin?.isActive = false + } + + open func alignRight() { + alignCenterPin?.isActive = false + alignCenterLeftPin?.isActive = true + alignCenterRightPin?.isActive = false + leftPin?.isActive = false + rightPin?.isActive = true + } + + open override func setLeftPinConstant(_ constant: CGFloat) { + super.setLeftPinConstant(constant) + alignCenterLeftPin?.constant = constant + } + + open override func setRightPinConstant(_ constant: CGFloat) { + super.setRightPinConstant(constant) + alignCenterRightPin?.constant = constant + } + + open override func resetConstraints() { + super.resetConstraints() + primaryButton?.isEnabled = false + } +} diff --git a/MVMCoreUI/Molecules/StandardFooterView.swift b/MVMCoreUI/Molecules/StandardFooterView.swift index 1e1f7b76..2cf85302 100644 --- a/MVMCoreUI/Molecules/StandardFooterView.swift +++ b/MVMCoreUI/Molecules/StandardFooterView.swift @@ -9,7 +9,7 @@ import UIKit public class StandardFooterView: ViewConstrainingView { - let twoButtonView = PrimaryButtonView(frame: .zero) + let twoButtonView = TwoButtonView(frame: .zero) var textButton = MFTextButton(nil, constrainHeight: true, forWidth: MVMCoreUIUtility.getWidth()) var spaceBetweenButtons: NSLayoutConstraint? var leftConstraintTwoButton: NSLayoutConstraint? @@ -34,7 +34,9 @@ public class StandardFooterView: ViewConstrainingView { translatesAutoresizingMaskIntoConstraints = false backgroundColor = .clear clipsToBounds = true - + setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical) + setContentCompressionResistancePriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical) + addSubview(twoButtonView) addSubview(textButton) @@ -66,7 +68,7 @@ public class StandardFooterView: ViewConstrainingView { } public func setSpacing() { - if twoButtonView.subviews.count > 0 && textButton.title(for: UIControl.State.normal)?.count ?? 0 > 0 { + if !(twoButtonView.heightConstraint?.isActive ?? false) && textButton.title(for: UIControl.State.normal)?.count ?? 0 > 0 { spaceBetweenButtons?.constant = PaddingTwo show() } else if twoButtonView.subviews.count > 0 || textButton.title(for: UIControl.State.normal)?.count ?? 0 > 0 { diff --git a/MVMCoreUI/Molecules/TwoButtonView.swift b/MVMCoreUI/Molecules/TwoButtonView.swift new file mode 100644 index 00000000..4ae821d2 --- /dev/null +++ b/MVMCoreUI/Molecules/TwoButtonView.swift @@ -0,0 +1,199 @@ +// +// TwoButtonView.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 3/21/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers open class TwoButtonView: ButtonView { + open var secondaryButton: PrimaryButton? + open var viewForButtons = MVMCoreUICommonViewsUtility.commonView() + public var heightConstraint: NSLayoutConstraint? + + public override init() { + super.init(frame: .zero) + } + + required public init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + public override init(frame: CGRect) { + super.init(frame: frame) + } + + // MARK: - MVMCoreViewProtocol + open override func updateView(_ size: CGFloat) { + super.updateView(size) + MVMCoreDispatchUtility.performBlock(onMainThread: { + self.secondaryButton?.updateView(size) + }) + } + + // MARK: - MVMCoreUIMoleculeViewProtocol + open override func setWithJSON(_ json: [AnyHashable : Any]?, delegate: NSObject?, additionalData: [AnyHashable : Any]?) { + super.setWithJSON(json, delegate: delegate, additionalData: additionalData) + if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) { + backgroundColor = UIColor.mfGet(forHex: backgroundColorString) + } + let primaryButtonMap = json?.optionalDictionaryForKey("primaryButton") + let secondaryButtonMap = json?.optionalDictionaryForKey("secondaryButton") + setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap) + primaryButton?.setAsStandardCustom() + secondaryButton?.setAsSecondaryCustom() + primaryButton?.setWithJSON(primaryButtonMap, delegate: delegate, additionalData: additionalData) + secondaryButton?.setWithJSON(secondaryButtonMap, delegate: delegate, additionalData: additionalData) + } + + // MARK: - Constraining + override func setupButton() { + guard viewForButtons.superview != self else { + return + } + addSubview(viewForButtons) + setupConstraints(forView: viewForButtons) + setupWithTwoButtons() + } + + open func setupWithTwoButtons() { + guard viewForButtons != primaryButton?.superview && viewForButtons != secondaryButton?.superview else { + return + } + if let primaryButton = primaryButton { + primaryButton.removeFromSuperview() + } else { + primaryButton = PrimaryButton.button() + } + if let secondaryButton = secondaryButton { + secondaryButton.removeFromSuperview() + } else { + secondaryButton = PrimaryButton.button() + secondaryButton?.bordered = true + } + guard let primaryButton = primaryButton, let secondaryButton = secondaryButton else { + return + } + viewForButtons.addSubview(primaryButton) + viewForButtons.addSubview(secondaryButton) + secondaryButton.widthAnchor.constraint(equalTo: primaryButton.widthAnchor, multiplier: 1).isActive = true + secondaryButton.topAnchor.constraint(equalTo: viewForButtons.topAnchor).isActive = true + primaryButton.topAnchor.constraint(equalTo: viewForButtons.topAnchor).isActive = true + viewForButtons.bottomAnchor.constraint(equalTo: secondaryButton.bottomAnchor).isActive = true + viewForButtons.bottomAnchor.constraint(equalTo: primaryButton.bottomAnchor).isActive = true + NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[leftButton]-10-[rightButton]-0-|", options: NSLayoutConstraint.FormatOptions.alignAllCenterY, metrics: nil, views: ["leftButton": secondaryButton, "rightButton": primaryButton])) + } + + open func setupWithPrimaryButton() { + primaryButton?.removeFromSuperview() + secondaryButton?.removeFromSuperview() + secondaryButton = nil + if primaryButton == nil { + primaryButton = PrimaryButton.button() + } + setupWithOneButton(primaryButton!) + } + + open func setupWithSecondaryButton() { + primaryButton?.removeFromSuperview() + secondaryButton?.removeFromSuperview() + primaryButton = nil + if secondaryButton == nil { + secondaryButton = PrimaryButton.button() + secondaryButton?.bordered = true + } + setupWithOneButton(secondaryButton!) + } + + func setupWithOneButton(_ button: PrimaryButton) { + viewForButtons.addSubview(button) + button.topAnchor.constraint(equalTo: viewForButtons.topAnchor).isActive = true + button.leftAnchor.constraint(equalTo: viewForButtons.leftAnchor).isActive = true + viewForButtons.rightAnchor.constraint(equalTo: button.rightAnchor).isActive = true + viewForButtons.bottomAnchor.constraint(equalTo: button.bottomAnchor).isActive = true + } + + open func setupUI(withPrimaryButtonMap primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?) { + if primaryButtonMap != nil, secondaryButtonMap != nil { + heightConstraint?.isActive = false + setupWithTwoButtons() + } else if primaryButtonMap != nil || secondaryButtonMap != nil { + heightConstraint?.isActive = false + setupWithPrimaryButton() + } else { + primaryButton?.removeFromSuperview() + secondaryButton?.removeFromSuperview() + primaryButton = nil + secondaryButton = nil + if heightConstraint == nil { + self.heightConstraint = heightAnchor.constraint(equalToConstant: 0) + self.heightConstraint?.isActive = true + } + } + } + + // MARK: - Legacy + open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { + let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton) + let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton) + setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) + } + + open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { + setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap) + if primaryButtonMap != nil, secondaryButtonMap != nil { + primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) + secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) + } else if primaryButtonMap != nil { + primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) + } else { + primaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) + } + } + + public convenience init(buttonSmall small: Bool, enabled: Bool) { + self.init() + setupWithPrimaryButton() + primaryButton?.setAsSmall(small) + primaryButton?.isEnabled = enabled + } + + public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: AnyHashable]?, buttonDelegate: Any?) { + self.init() + setup(withButtonMap: buttonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonMap) + primaryButton?.setAsSmall(small) + secondaryButton?.setAsSmall(small) + } + + public convenience init(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { + self.init() + setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) + } + + public func hidePrimaryLeftButton() { + if let secondaryButton = secondaryButton, !secondaryButton.isHidden { + secondaryButton.isHidden = true + setupWithPrimaryButton() + } + } + + public func hidePrimaryRightButton() { + if let primaryButton = primaryButton, !primaryButton.isHidden { + primaryButton.isHidden = true + setupWithSecondaryButton() + } + } + + public func showBothPrimaryButtons() { + primaryButton?.isHidden = false + secondaryButton?.isHidden = false + setupWithTwoButtons() + } + + public func hideBothPrimaryButtons() { + primaryButton?.isHidden = true + secondaryButton?.isHidden = true + } +} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index 3c36a612..304f8faf 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -23,11 +23,11 @@ mapping = [@{ @"label": LabelView.class, @"separator": SeparatorView.class, - @"button": MFCustomButton.class, + @"button": ButtonView.class, @"textButton": MFTextButton.class, @"standardHeader": StandardHeaderView.class, @"moleculeStack": MoleculeStackView.class, - @"twoButtonView": PrimaryButtonView.class, + @"twoButtonView": TwoButtonView.class, @"standardFooter": StandardFooterView.class } mutableCopy]; });