diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index b532841b..0ebd9799 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -274,9 +274,12 @@ D236E5B5241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */; }; D236E5B7242007C500C38625 /* MVMControllerModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */; }; D23EA7FB2475F09800D60C34 /* CarouselItemProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */; }; + D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */; }; + D23EA800247EBD6C00D60C34 /* LabelBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */; }; + D23EA802247EBED400D60C34 /* ImageBarButtonItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D23EA801247EBED400D60C34 /* ImageBarButtonItem.swift */; }; D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; }; D2509ED12472ED9B001BFB9D /* NavigationItemModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */; }; - D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */; }; + D2509ED62472EE2F001BFB9D /* NavigationImageButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2509ED52472EE2F001BFB9D /* NavigationImageButtonModel.swift */; }; D253BB8A24574CC5002DE544 /* StackModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D260106423D0CEA700764D80 /* StackModel.swift */; }; D253BB9C245874F8002DE544 /* BGImageMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9B245874F8002DE544 /* BGImageMolecule.swift */; }; D253BB9E2458751F002DE544 /* BGImageMoleculeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */; }; @@ -323,6 +326,7 @@ D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */; }; D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A839023CD4FD400DFE4FC /* CornerLabelsModel.swift */; }; D28A839323CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28A839223CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift */; }; + D28BA730247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D28BA72F247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift */; }; D296E14722A5984C0051EBE7 /* MVMCoreUIViewConstrainingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */; }; D29C94D5242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29C94D4242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift */; }; @@ -699,9 +703,12 @@ D236E5B3241FEB1000C38625 /* ListTwoColumnPriceDescriptionModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ListTwoColumnPriceDescriptionModel.swift; sourceTree = ""; }; D236E5B6242007C500C38625 /* MVMControllerModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMControllerModelProtocol.swift; sourceTree = ""; }; D23EA7FA2475F09800D60C34 /* CarouselItemProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CarouselItemProtocol.swift; sourceTree = ""; }; + D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationLabelButtonModel.swift; sourceTree = ""; }; + D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelBarButtonItem.swift; sourceTree = ""; }; + D23EA801247EBED400D60C34 /* ImageBarButtonItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageBarButtonItem.swift; sourceTree = ""; }; D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = ""; }; D2509ED02472ED9B001BFB9D /* NavigationItemModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationItemModelProtocol.swift; sourceTree = ""; }; - D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationItemButtonModel.swift; sourceTree = ""; }; + D2509ED52472EE2F001BFB9D /* NavigationImageButtonModel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NavigationImageButtonModel.swift; sourceTree = ""; }; D253BB9B245874F8002DE544 /* BGImageMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMolecule.swift; sourceTree = ""; }; D253BB9D2458751F002DE544 /* BGImageMoleculeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BGImageMoleculeModel.swift; sourceTree = ""; }; D256E9922412880000360572 /* Header.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Header.swift; sourceTree = ""; }; @@ -746,6 +753,7 @@ D28A838E23CCDEDE00DFE4FC /* TwoButtonViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonViewModel.swift; sourceTree = ""; }; D28A839023CD4FD400DFE4FC /* CornerLabelsModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerLabelsModel.swift; sourceTree = ""; }; D28A839223CE828900DFE4FC /* HeadlineBodyCaretLinkImageModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyCaretLinkImageModel.swift; sourceTree = ""; }; + D28BA72F247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NavigationButtomModelProtocol.swift; sourceTree = ""; }; D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewConstrainingProtocol.h; sourceTree = ""; }; D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleMolecule.swift; sourceTree = ""; }; D29C94D4242901C9003813BA /* MVMCoreUICommonViewsUtility+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MVMCoreUICommonViewsUtility+Extension.swift"; sourceTree = ""; }; @@ -1361,10 +1369,22 @@ path = TwoColumn; sourceTree = ""; }; + D23EA7FC247EBB7500D60C34 /* Buttons */ = { + isa = PBXGroup; + children = ( + D28BA72F247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift */, + D2509ED52472EE2F001BFB9D /* NavigationImageButtonModel.swift */, + D23EA801247EBED400D60C34 /* ImageBarButtonItem.swift */, + D23EA7FD247EBBB700D60C34 /* NavigationLabelButtonModel.swift */, + D23EA7FF247EBD6C00D60C34 /* LabelBarButtonItem.swift */, + ); + path = Buttons; + sourceTree = ""; + }; D2509ED42472EE0B001BFB9D /* NavigationBar */ = { isa = PBXGroup; children = ( - D2509ED52472EE2F001BFB9D /* NavigationItemButtonModel.swift */, + D23EA7FC247EBB7500D60C34 /* Buttons */, D20FB164241A5D75004AFC3A /* NavigationItemModel.swift */, ); path = NavigationBar; @@ -1976,7 +1996,7 @@ 8D3BA9BF2433789900D341BA /* ListThreeColumnInternationalDataDivider.swift in Sources */, 94C661DA23CCF4FB00D9FE5B /* UIColor+Extension.swift in Sources */, D28A838123CCB0D800DFE4FC /* AccordionListItemModel.swift in Sources */, - D2509ED62472EE2F001BFB9D /* NavigationItemButtonModel.swift in Sources */, + D2509ED62472EE2F001BFB9D /* NavigationImageButtonModel.swift in Sources */, 32F8804824765C8400C2ACB3 /* ListLeftVariableNumberedListAllTextAndLinks.swift in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */, C07065C42395677300FBF997 /* Link.swift in Sources */, @@ -2153,7 +2173,9 @@ BB54C5212434D92F0038326C /* ListRightVariableButtonAllTextAndLinksModel.swift in Sources */, D2092349244A51D40044AD09 /* RadioSwatchModel.swift in Sources */, 8DD1E370243B3D0500D8F2DF /* ListThreeColumnInternationalData.swift in Sources */, + D23EA802247EBED400D60C34 /* ImageBarButtonItem.swift in Sources */, D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */, + D23EA800247EBD6C00D60C34 /* LabelBarButtonItem.swift in Sources */, 01EB368F23609801006832FA /* LabelModel.swift in Sources */, 0A6682AC243531C300AD3CA1 /* Padding.swift in Sources */, AA1EC59924373994003D6F50 /* ListThreeColumnSpeedTestDivider.swift in Sources */, @@ -2223,6 +2245,7 @@ BBAA4F03243D8E3B005AAD5F /* RadioBoxes.swift in Sources */, D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */, 525019E72406853600EED91C /* ListFourColumnDataUsageDivider.swift in Sources */, + D28BA730247EC2EB00B75CB8 /* NavigationButtomModelProtocol.swift in Sources */, 0AE98BB323FF0934004C5109 /* ExternalLinkModel.swift in Sources */, D20FB165241A5D75004AFC3A /* NavigationItemModel.swift in Sources */, AA2AD118244EE48C00BBFFE3 /* ListDeviceComplexLinkMediumModel.swift in Sources */, @@ -2291,6 +2314,7 @@ 94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */, D28A838523CCCA8900DFE4FC /* ScrollerModel.swift in Sources */, D29DF26C21E6AA0B003B2FB9 /* FLAnimatedImage.m in Sources */, + D23EA7FE247EBBB700D60C34 /* NavigationLabelButtonModel.swift in Sources */, D28A839123CD4FD400DFE4FC /* CornerLabelsModel.swift in Sources */, 012A88F123985E0100FE3DA1 /* Color.swift in Sources */, D22D8393241C27B100D3DF69 /* TemplateModel.swift in Sources */, diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift index b0e4d54d..0881af71 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift @@ -11,7 +11,7 @@ import UIKit public typealias FacadeElements = (fill: UIColor?, text: UIColor?, border: UIColor?) -public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWatcherFieldProtocol { +public class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWatcherFieldProtocol, EnableableModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift index 5a4a4c14..a37baeca 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/CaretLinkModel.swift @@ -10,7 +10,7 @@ import Foundation import MVMCore -public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol { +public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift index d51bddf4..bd1b601d 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/Link/LinkModel.swift @@ -9,7 +9,7 @@ import UIKit -open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol { +open class LinkModel: ButtonModelProtocol, MoleculeModelProtocol, EnableableModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/ImageBarButtonItem.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/ImageBarButtonItem.swift new file mode 100644 index 00000000..564b9f42 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/ImageBarButtonItem.swift @@ -0,0 +1,45 @@ +// +// ImageBarButtonItem.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/27/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class ImageBarButtonItem: BarButtonItem { + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + + public static func create(with image: UIImage?) -> Self { + let actionObject = ActionDelegate() + let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:))) + button.actionDelegate = actionObject + return button + } + + /// Creates the item with the passed in action. + public static func create(with image: UIImage?, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + let button = create(with: image) + button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) + return button + } + + /// Creates the item with the passed in action map. + public static func create(with image: UIImage?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + let button = create(with: image) + button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) + return button + } + + /// Creates the item with the passed in action. + public static func create(with image: UIImage?, action: @escaping BarButtonAction) -> Self { + let button = create(with: image) + button.actionDelegate?.buttonAction = action + return button + } +} + diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/LabelBarButtonItem.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/LabelBarButtonItem.swift new file mode 100644 index 00000000..4d31a84c --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/LabelBarButtonItem.swift @@ -0,0 +1,44 @@ +// +// LabelBarButtonItem.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/27/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +@objcMembers open class LabelBarButtonItem: BarButtonItem { + + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + + public static func create(with title: String?) -> Self { + let actionObject = ActionDelegate() + let button = self.init(title: title, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:))) + button.actionDelegate = actionObject + return button + } + + /// Creates the item with the passed in action. + public static func create(with title: String?, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + let button = create(with: title) + button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) + return button + } + + /// Creates the item with the passed in action map. + public static func create(with title: String?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { + let button = create(with: title) + button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) + return button + } + + /// Creates the item with the passed in action. + public static func create(with title: String?, action: @escaping BarButtonAction) -> Self { + let button = create(with: title) + button.actionDelegate?.buttonAction = action + return button + } +} diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift new file mode 100644 index 00000000..3f38ce43 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationButtomModelProtocol.swift @@ -0,0 +1,15 @@ +// +// NavigationButtomModelProtocol.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/27/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public protocol NavigationButtomModelProtocol: ButtonModelProtocol { + //var color: Color? { get set } + + func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> BarButtonItem +} diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift similarity index 74% rename from MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift rename to MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift index 26be6952..b4173e8b 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemButtonModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationImageButtonModel.swift @@ -7,9 +7,12 @@ import Foundation -public class NavigationItemButtonModel: Codable { - var imageName: String - var action: ActionModelProtocol +public class NavigationImageButtonModel: NavigationButtomModelProtocol, MoleculeModelProtocol { + public var backgroundColor: Color? + public static var identifier: String = "navigationImageButton" + + public var imageName: String + public var action: ActionModelProtocol public init(with imageName: String, action: ActionModelProtocol) { self.imageName = imageName @@ -36,6 +39,6 @@ public class NavigationItemButtonModel: Codable { /// Convenience function that creates a BarButtonItem for the model. public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem { let image = UIImage(named: imageName, in: MVMCoreCache.shared()?.bundleToUseForImages(), compatibleWith: nil) - return BarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) + return ImageBarButtonItem.create(with: image, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) } } diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift new file mode 100644 index 00000000..6b253459 --- /dev/null +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/Buttons/NavigationLabelButtonModel.swift @@ -0,0 +1,44 @@ +// +// NavigationLabelButtonModel.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 5/27/20. +// Copyright © 2020 Verizon Wireless. All rights reserved. +// + +import Foundation + +public class NavigationLabelButtonModel: NavigationButtomModelProtocol, MoleculeModelProtocol { + public var backgroundColor: Color? + public static var identifier: String = "navigationLabelButton" + + public var title: String + public var action: ActionModelProtocol + + public init(with title: String, action: ActionModelProtocol) { + self.title = title + self.action = action + } + + private enum CodingKeys: String, CodingKey { + case title + case action + } + + required public init(from decoder: Decoder) throws { + let typeContainer = try decoder.container(keyedBy: CodingKeys.self) + title = try typeContainer.decode(String.self, forKey: .title) + action = try typeContainer.decodeModel(codingKey: .action) + } + + open func encode(to encoder: Encoder) throws { + var container = encoder.container(keyedBy: CodingKeys.self) + try container.encode(title, forKey: .title) + try container.encodeModel(action, forKey: .action) + } + + /// Convenience function that creates a BarButtonItem for the model. + public func createNavigationItemButton(delegateObject: MVMCoreUIDelegateObject? = nil, additionalData: [AnyHashable: Any]? = nil) -> BarButtonItem { + return LabelBarButtonItem.create(with: title, actionModel: action, delegateObject: delegateObject, additionalData: additionalData) + } +} diff --git a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift index b62bb399..f29f1e38 100644 --- a/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/NavigationBar/NavigationItemModel.swift @@ -18,16 +18,16 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt public var backgroundColor: Color? public var tintColor: Color public var line: LineModel? - public var backButton: NavigationItemButtonModel? - public var additionalLeftButtons: [NavigationItemButtonModel]? - public var additionalRightButtons: [NavigationItemButtonModel]? + public var backButton: (NavigationButtomModelProtocol & MoleculeModelProtocol)? + public var additionalLeftButtons: [(NavigationButtomModelProtocol & MoleculeModelProtocol)]? + public var additionalRightButtons: [(NavigationButtomModelProtocol & MoleculeModelProtocol)]? public init() { hidden = false backgroundColor = Color(uiColor: .white) tintColor = Color(uiColor: .black) line = LineModel(type: .standard) - backButton = NavigationItemButtonModel(with: "back", action: ActionBackModel()) + backButton = NavigationImageButtonModel(with: "back", action: ActionBackModel()) } private enum CodingKeys: String, CodingKey { @@ -50,9 +50,9 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) ?? Color(uiColor: .white) tintColor = try typeContainer.decodeIfPresent(Color.self, forKey: .tintColor) ?? Color(uiColor: .black) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) - backButton = try typeContainer.decodeIfPresent(NavigationItemButtonModel.self, forKey: .backButton) ?? NavigationItemButtonModel(with: "back", action: ActionBackModel()) - additionalLeftButtons = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalLeftButtons) - additionalRightButtons = try typeContainer.decodeIfPresent([NavigationItemButtonModel].self, forKey: .additionalRightButtons) + backButton = try typeContainer.decodeModelIfPresent(codingKey: .backButton) ?? NavigationImageButtonModel(with: "back", action: ActionBackModel()) + additionalLeftButtons = try typeContainer.decodeModels(codingKey: .additionalLeftButtons) + additionalRightButtons = try typeContainer.decodeModels(codingKey: .additionalRightButtons) } open func encode(to encoder: Encoder) throws { @@ -62,8 +62,8 @@ public class NavigationItemModel: NavigationItemModelProtocol, MoleculeModelProt try container.encode(backgroundColor, forKey: .backgroundColor) try container.encode(tintColor, forKey: .tintColor) try container.encodeIfPresent(line, forKey: .line) - try container.encodeIfPresent(backButton, forKey: .backButton) - try container.encodeIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons) - try container.encodeIfPresent(additionalRightButtons, forKey: .additionalRightButtons) + try container.encodeModelIfPresent(backButton, forKey: .backButton) + try container.encodeModelsIfPresent(additionalLeftButtons, forKey: .additionalLeftButtons) + try container.encodeModelsIfPresent(additionalRightButtons, forKey: .additionalRightButtons) } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ButtonModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ButtonModelProtocol.swift index 1288f4e3..71c3b232 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ButtonModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ButtonModelProtocol.swift @@ -8,6 +8,6 @@ import Foundation -public protocol ButtonModelProtocol: EnableableModelProtocol { +public protocol ButtonModelProtocol { var action: ActionModelProtocol { get set } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift index 0bd192e3..e6491ac3 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/NavigationItemModelProtocol.swift @@ -14,7 +14,7 @@ public protocol NavigationItemModelProtocol { var backgroundColor: Color? { get set } var tintColor: Color { get set } var line: LineModel? { get set } - var backButton: NavigationItemButtonModel? { get set } - var additionalLeftButtons: [NavigationItemButtonModel]? { get set } - var additionalRightButtons: [NavigationItemButtonModel]? { get set } + var backButton: (NavigationButtomModelProtocol & MoleculeModelProtocol)? { get set } + var additionalLeftButtons: [(NavigationButtomModelProtocol & MoleculeModelProtocol)]? { get set } + var additionalRightButtons: [(NavigationButtomModelProtocol & MoleculeModelProtocol)]? { get set } } diff --git a/MVMCoreUI/BaseClasses/BarButtonItem.swift b/MVMCoreUI/BaseClasses/BarButtonItem.swift index ac26c040..f2da9c7c 100644 --- a/MVMCoreUI/BaseClasses/BarButtonItem.swift +++ b/MVMCoreUI/BaseClasses/BarButtonItem.swift @@ -8,9 +8,9 @@ public typealias BarButtonAction = (BarButtonItem) -> () -@objc fileprivate class ActionDelegate: NSObject { - fileprivate var buttonAction: BarButtonAction? - @objc fileprivate func callActionBlock(_ sender: BarButtonItem) { +@objc internal class ActionDelegate: NSObject { + internal var buttonAction: BarButtonAction? + @objc internal func callActionBlock(_ sender: BarButtonItem) { buttonAction?(sender) } } @@ -22,39 +22,7 @@ public typealias BarButtonAction = (BarButtonItem) -> () //-------------------------------------------------- open weak var buttonDelegate: ButtonDelegateProtocol? - private var actionDelegate: ActionDelegate? - - //-------------------------------------------------- - // MARK: - Initializers - //-------------------------------------------------- - - public static func create(with image: UIImage?) -> Self { - let actionObject = ActionDelegate() - let button = self.init(image: image, style: .plain, target: actionObject, action: #selector(actionObject.callActionBlock(_:))) - button.actionDelegate = actionObject - return button - } - - /// Creates the item with the passed in action. - public static func create(with image: UIImage?, actionModel: ActionModelProtocol, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { - let button = create(with: image) - button.set(with: actionModel, delegateObject: delegateObject, additionalData: additionalData) - return button - } - - /// Creates the item with the passed in action map. - public static func create(with image: UIImage?, actionMap: [AnyHashable : Any], delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Self { - let button = create(with: image) - button.set(with: actionMap, delegateObject: delegateObject, additionalData: additionalData) - return button - } - - /// Creates the item with the passed in action. - public static func create(with image: UIImage?, action: @escaping BarButtonAction) -> Self { - let button = create(with: image) - button.actionDelegate?.buttonAction = action - return button - } + internal var actionDelegate: ActionDelegate? //-------------------------------------------------- // MARK: - Methods diff --git a/MVMCoreUI/BaseClasses/Button.swift b/MVMCoreUI/BaseClasses/Button.swift index f4ab51c6..5d42c5fb 100644 --- a/MVMCoreUI/BaseClasses/Button.swift +++ b/MVMCoreUI/BaseClasses/Button.swift @@ -94,9 +94,11 @@ public typealias ButtonAction = (Button) -> () self.backgroundColor = backgroundColor.uiColor } - guard let model = model as? ButtonModelProtocol else { return } + if let model = model as? EnableableModelProtocol { + isEnabled = model.enabled + } - isEnabled = model.enabled + guard let model = model as? ButtonModelProtocol else { return } set(with: model.action, delegateObject: delegateObject, additionalData: additionalData) } diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index eb92dd85..0e313ac8 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -189,22 +189,28 @@ import UIKit // MARK: - Navigation Item (Move to model base) open func setNavigationController() { + let viewController = manager ?? self guard let navigationItemModel = pageModel?.navigationItem, - let navigationController = manager?.navigationController ?? navigationController else { + let navigationController = viewController.navigationController else { MVMCoreUISession.sharedGlobal()?.splitViewController?.parent?.setNeedsStatusBarAppearanceUpdate() return } - let viewController = manager ?? self - if navigationController == MVMCoreUISplitViewController.main()?.navigationController, - navigationController.topViewController == viewController { - MVMCoreUISession.sharedGlobal()?.splitViewController?.setupPanels() - showBottomProgressBar() - } + + // We additionally want our left items + navigationItem.leftItemsSupplementBackButton = true + NavigationController.set(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) - // TODO: Legacy Update Panels. Change how this is done. + // Special logic when using the split view controller. Legacy Update Panels. Change how this is done. + guard navigationController == MVMCoreUISplitViewController.main()?.navigationController, + navigationController.topViewController == viewController else { return } + + MVMCoreUISession.sharedGlobal()?.splitViewController?.setupPanels() + showBottomProgressBar() + MVMCoreUISplitViewController.main()?.setLeftPanelIsAccessible(isMasterInitiallyAccessible(), for: viewController) MVMCoreUISplitViewController.main()?.setRightPanelIsAccessible(isSupportInitiallyAccessible(), for: viewController) + MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(navigationItemModel.tintColor.uiColor) } // Eventually will be moved to server diff --git a/MVMCoreUI/Containers/NavigationController.swift b/MVMCoreUI/Containers/NavigationController.swift index 0b2d1546..ab57f9f8 100644 --- a/MVMCoreUI/Containers/NavigationController.swift +++ b/MVMCoreUI/Containers/NavigationController.swift @@ -84,16 +84,8 @@ import UIKit if let navigationController = navigationController as? NavigationController { navigationController.separatorView?.isHidden = navigationItemModel.line?.type ?? .standard == .none } - - // Let legacy splitview controller handle buttons for now. - guard navigationController == MVMCoreUISplitViewController.main()?.navigationController, - navigationController.topViewController == viewController else { - // Not the main split view controller, add buttons. - setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) - return - } - - // Update icons if main navigation controller. - MVMCoreUISession.sharedGlobal()?.splitViewController?.setNavigationIconColor(tint) + + // Sets up the navigation buttons. + setNavigationButtons(navigationController: navigationController, navigationItemModel: navigationItemModel, viewController: viewController) } } diff --git a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m index d9814a1f..0ce218b2 100644 --- a/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m +++ b/MVMCoreUI/Containers/SplitViewController/MVMCoreUISplitViewController.m @@ -107,29 +107,12 @@ CGFloat const PanelAnimationDuration = 0.2; return (width > 2000 ? MFTwoDrawer : (width > 1000 ? MFOneDrawer : MFNoDrawer)); } -- (nullable UIBarButtonItem *)getBackButtonForViewController:(nonnull UIViewController *)viewController { - if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return self.backButton; } - UIViewController *controller = (UIViewController *)viewController; - NSDictionary *item = [controller.loadObject.pageJSON dictWithChainOfKeysOrIndexes:@[@"navigationItem",@"backButton"]]; - if (!item) { return self.backButton; } - DelegateObject *delegate = [controller delegateObject]; - return [self createNavigationItemButtonFrom:item delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; -} - - (nullable NSArray *)additionalLeftButtonsForViewController:(nonnull UIViewController *)viewController { - if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return nil; } - UIViewController *controller = (UIViewController *)viewController; - NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalLeftButtons"]]; - DelegateObject *delegate = [controller delegateObject]; - return [self createNavigationItemButtonsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; + return viewController.navigationItem.leftBarButtonItems; } - (nullable NSArray *)additionalRightButtonsForViewController:(nonnull UIViewController *)viewController { - if (![viewController conformsToProtocol:@protocol(MVMCoreViewControllerProtocol)]) { return nil; } - UIViewController *controller = (UIViewController *)viewController; - NSArray *items = [controller.loadObject.pageJSON arrayForChainOfKeysOrIndexes:@[@"navigationItem",@"additionalRightButtons"]]; - DelegateObject *delegate = [controller delegateObject]; - return [self createNavigationItemButtonsFrom:items delegateObject:[delegate isKindOfClass:[MVMCoreUIDelegateObject class]] ? (MVMCoreUIDelegateObject *)delegate : nil]; + return viewController.navigationItem.rightBarButtonItems; } - (CGFloat)leftPanelExtendedWidth { @@ -251,15 +234,6 @@ CGFloat const PanelAnimationDuration = 0.2; - (void)setLeftNavigationItemForViewController:(UIViewController * _Nonnull)viewController accessible:(BOOL)accessible extended:(BOOL)extended { NSMutableArray *leftBarButtonItems = [NSMutableArray array]; - if ([viewController.navigationController.viewControllers count] > 1) { - UIBarButtonItem *button = [self getBackButtonForViewController:viewController]; - if (button) { - viewController.navigationItem.hidesBackButton = YES; - [leftBarButtonItems addObject:button]; - } else { - viewController.navigationItem.hidesBackButton = NO; - } - } if ((accessible && !extended) && self.leftPanelButton) { [leftBarButtonItems addObject:self.leftPanelButton]; } @@ -625,24 +599,6 @@ CGFloat const PanelAnimationDuration = 0.2; #pragma mark - Other Panel Functions -/// Convenience function, creates a BarButtonItem from button json -- (nonnull UIBarButtonItem *)createNavigationItemButtonFrom:(nonnull NSDictionary *)JSON delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { - UIImage *image = [UIImage imageNamed:[JSON string:@"imageName"] inBundle:[[MVMCoreCache sharedCache] bundleToUseForImages] compatibleWithTraitCollection:nil]; - BarButtonItem *item = [BarButtonItem createWith:image actionMap:[JSON dict:@"action"] delegateObject:delegateObject additionalData:nil]; - return item; -} - -/// Convenience function, creates a list of BarButtonItems list of json -- (nullable NSArray *)createNavigationItemButtonsFrom:(nullable NSArray *)JSONlist delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { - if (JSONlist.count == 0) { return nil; } - NSMutableArray *items = [NSMutableArray arrayWithCapacity:JSONlist.count]; - for (NSDictionary *itemData in JSONlist) { - UIBarButtonItem *item = [self createNavigationItemButtonFrom:itemData delegateObject:delegateObject]; - [items addObject:item]; - } - return items; -} - - (void)forceHideBothDrawers { [self hideBothDrawersShouldForceHide:YES]; }