diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 1394ec88..cb13de6f 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -1239,6 +1239,18 @@ path = "Date Dropdown"; sourceTree = ""; }; + 0A1C30972620F61A00B47F3B /* Protocols */ = { + isa = PBXGroup; + children = ( + D23A8FF72612308D007E14CE /* PageBehaviorProtocolRequirer.swift */, + D23A8FFA26123189007E14CE /* PageBehaviorModelProtocol.swift */, + D23A8FFF2612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift */, + D23A9003261234CE007E14CE /* PageBehaviorHandlerProtocol.swift */, + 27F973522466074500CAB5C5 /* PageBehaviorProtocol.swift */, + ); + path = Protocols; + sourceTree = ""; + }; 0A5D59C323AD488600EFD9E9 /* Protocols */ = { isa = PBXGroup; children = ( @@ -1296,11 +1308,7 @@ 27F973512466071600CAB5C5 /* Behaviors */ = { isa = PBXGroup; children = ( - D23A8FF72612308D007E14CE /* PageBehaviorProtocolRequirer.swift */, - D23A8FFA26123189007E14CE /* PageBehaviorModelProtocol.swift */, - D23A8FFF2612347A007E14CE /* PageBehaviorHandlerModelProtocol.swift */, - D23A9003261234CE007E14CE /* PageBehaviorHandlerProtocol.swift */, - 27F973522466074500CAB5C5 /* PageBehaviorProtocol.swift */, + 0A1C30972620F61A00B47F3B /* Protocols */, 27F97369246750BE00CAB5C5 /* ScreenBrightnessModifierBehavior.swift */, D23A900826125FFB007E14CE /* GetContactBehavior.swift */, ); diff --git a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift index 641d995c..9814a44a 100644 --- a/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift +++ b/MVMCoreUI/Atomic/Atoms/Buttons/ButtonModel.swift @@ -16,9 +16,7 @@ open class ButtonModel: ButtonModelProtocol, MoleculeModelProtocol, FormGroupWat // MARK: - Properties //-------------------------------------------------- //Making static property as class property so that subclasses can override getter function of the property - open class var identifier: String { - "button" - } + open class var identifier: String { "button" } public var backgroundColor: Color? public var accessibilityIdentifier: String? public var title: String diff --git a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift index e8c8446f..026e9acf 100644 --- a/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift +++ b/MVMCoreUI/Atomic/Atoms/Views/Label/Label.swift @@ -625,7 +625,7 @@ public typealias ActionBlock = () -> () font = font.updateSize(sizeObject.getValueBased(onSize: size)) } } - + @objc public func setFont(_ font: UIFont, scale: Bool) { self.font = font setScale(scale) @@ -829,6 +829,7 @@ extension Label { private func addActionAttributes(range: NSRange, string: NSMutableAttributedString?) { guard let string = string else { return } + string.addAttributes([NSAttributedString.Key.underlineStyle: NSUnderlineStyle.single.rawValue], range: range) } diff --git a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Miscellaneous/ListStoreLocator.swift b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Miscellaneous/ListStoreLocator.swift index d81ab5c8..b10b3069 100644 --- a/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Miscellaneous/ListStoreLocator.swift +++ b/MVMCoreUI/Atomic/Molecules/DesignedComponents/List/Miscellaneous/ListStoreLocator.swift @@ -7,18 +7,19 @@ // @objcMembers open class ListStoreLocator: TableViewCell { - //-------------------------------------------------- // MARK: - Outlets //-------------------------------------------------- + public let heart = Heart() public let leftHeadline = Label(fontStyle: .BoldBodySmall) public let leftBody = Label(fontStyle: .RegularBodySmall) public let leftSubBody = Label(fontStyle: .RegularBodySmall) public let rightLabel = Label(fontStyle: .RegularBodySmall) private lazy var rightLabelStackItem: StackItem = { - return StackItem(andContain: rightLabel) + StackItem(andContain: rightLabel) }() + public lazy var horizontalStack: Stack = { return Stack(with: StackModel(molecules: [StackItemModel(horizontalAlignment: .fill), StackItemModel(horizontalAlignment: .fill), @@ -83,9 +84,7 @@ } } - open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - return 120 - } + open override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 120 } open override func reset() { super.reset() @@ -98,6 +97,7 @@ //-------------------------------------------------- // MARK: - Accessibility //-------------------------------------------------- + func getAccessibilityMessage() -> String? { var message = "" heart.updateAccessibilityLabel() @@ -155,6 +155,6 @@ return .none } } - set {} + set { } } } diff --git a/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/FooterModel.swift b/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/FooterModel.swift index 12e0eca8..bab51c2d 100644 --- a/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/FooterModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/FooterModel.swift @@ -6,13 +6,9 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -import Foundation - @objcMembers public class FooterModel: MoleculeContainerModel { - public override class var identifier: String { - return "footer" - } + public override class var identifier: String { "footer" } /// Defaults to set public override func setDefaults() { diff --git a/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/Header.swift b/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/Header.swift index 6989a15e..73b42dea 100644 --- a/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/Header.swift +++ b/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/Header.swift @@ -12,7 +12,7 @@ open class HeaderView: Container { /// Convenience for doing some default setting open var molecule: MoleculeViewProtocol? - + var headerModel: HeaderModel? { get { model as? HeaderModel } } @@ -46,7 +46,7 @@ open class HeaderView: Container { line.setStyle(.heavy) molecule?.reset() } - + // MARK: - MoleculeViewProtocol open override func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { super.set(with: model, delegateObject, additionalData) diff --git a/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/HeaderModel.swift b/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/HeaderModel.swift index 09fe077f..08c7343f 100644 --- a/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/HeaderModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/HeaderModel.swift @@ -6,7 +6,6 @@ // Copyright © 2019 Suresh, Kamlesh. All rights reserved. // -import Foundation @objcMembers public class HeaderModel: ContainerModel { public var backgroundColor: Color? diff --git a/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/MoleculeSectionFooterModel.swift b/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/MoleculeSectionFooterModel.swift index edf9fc7a..56d7d0e3 100644 --- a/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/MoleculeSectionFooterModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/MoleculeSectionFooterModel.swift @@ -6,12 +6,17 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers open class MoleculeSectionFooterModel: MoleculeContainerModel, SectionListHeaderFooterModel { - public class override var identifier: String { - return "sectionFooter" - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public class override var identifier: String { "sectionFooter" } + + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- /// Defaults to set public override func setDefaults() { diff --git a/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/MoleculeSectionHeaderModel.swift b/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/MoleculeSectionHeaderModel.swift index ef6b057e..18360b30 100644 --- a/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/MoleculeSectionHeaderModel.swift +++ b/MVMCoreUI/Atomic/Molecules/HeadersAndFooters/MoleculeSectionHeaderModel.swift @@ -6,19 +6,27 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers open class MoleculeSectionHeaderModel: MoleculeContainerModel, SectionListHeaderFooterModel { - public class override var identifier: String { - return "sectionHeader" - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public class override var identifier: String { "sectionHeader" } public var line: LineModel? + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case line case backgroundColor } + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + /// Defaults to set public override func setDefaults() { if useHorizontalMargins == nil { @@ -38,6 +46,10 @@ import Foundation } } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { try super.init(from: decoder) let typeContainer = try decoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Atomic/Molecules/Items/AccordionListItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/AccordionListItemModel.swift index cd2c12aa..a19c3813 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/AccordionListItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/AccordionListItemModel.swift @@ -13,13 +13,11 @@ class AccordionListItemModel: MoleculeListItemModel { // MARK: - Properties //-------------------------------------------------- - override public class var identifier: String { - return "accordionListItem" - } + override public class var identifier: String { "accordionListItem" } public var molecules: [ListItemModelProtocol & MoleculeModelProtocol] public var hideLineWhenExpanded: Bool = false - + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- @@ -39,7 +37,7 @@ class AccordionListItemModel: MoleculeListItemModel { super.setDefaults() hideArrow = true } - + //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- @@ -52,7 +50,7 @@ class AccordionListItemModel: MoleculeListItemModel { } try super.init(from: decoder) } - + public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Atomic/Molecules/Items/AccordionMoleculeTableViewCell.swift b/MVMCoreUI/Atomic/Molecules/Items/AccordionMoleculeTableViewCell.swift index f7a493d7..46a1e651 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/AccordionMoleculeTableViewCell.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/AccordionMoleculeTableViewCell.swift @@ -13,7 +13,7 @@ //-------------------------------------------------- var accordionListItemModel: AccordionListItemModel? { - return listItemModel as? AccordionListItemModel + listItemModel as? AccordionListItemModel } let accordionButton: Button = { diff --git a/MVMCoreUI/Atomic/Molecules/Items/CarouselItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/CarouselItemModel.swift index 19348070..1d55cec3 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/CarouselItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/CarouselItemModel.swift @@ -6,24 +6,20 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -import Foundation - @objcMembers open class CarouselItemModel: MoleculeCollectionItemModel, CarouselItemModelProtocol { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - open override class var identifier: String { - return "carouselItem" - } + open override class var identifier: String { "carouselItem" } public var peakingUI: Bool? public var peakingArrowColor: Color? public var analyticsData: JSONValueDictionary? public var fieldValue: String? - public func formFieldValue() -> AnyHashable? { return fieldValue } + public func formFieldValue() -> AnyHashable? { fieldValue } //-------------------------------------------------- // MARK: - Keys diff --git a/MVMCoreUI/Atomic/Molecules/Items/ListItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/ListItemModel.swift index 4c34cc39..a5320ad2 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/ListItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/ListItemModel.swift @@ -7,11 +7,8 @@ // // A base class that has common list item boilerplate model stuffs. -import Foundation - @objcMembers open class ListItemModel: ContainerModel, ListItemModelProtocol { - //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionItemModel.swift index f9df766f..5523d08d 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/MoleculeCollectionItemModel.swift @@ -6,21 +6,29 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation /// A model for a collection item that is a container for any molecule. @objcMembers open class MoleculeCollectionItemModel: MoleculeContainerModel, CollectionItemModelProtocol { - open override class var identifier: String { - return "collectionItem" - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + open override class var identifier: String { "collectionItem" } public var action: ActionModelProtocol? + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case action } - /// Defaults to set + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + public override func setDefaults() { if useHorizontalMargins == nil { useHorizontalMargins = true @@ -36,9 +44,17 @@ import Foundation } } + //-------------------------------------------------- + // MARK: - Initialization + //-------------------------------------------------- + public override init(with moleculeModel: MoleculeModelProtocol) { super.init(with: moleculeModel) } + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Atomic/Molecules/Items/MoleculeListItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/MoleculeListItemModel.swift index 1028362e..9e230607 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/MoleculeListItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/MoleculeListItemModel.swift @@ -6,7 +6,6 @@ // Copyright © 2019 Suresh, Kamlesh. All rights reserved. // -import Foundation import MVMCore @@ -15,12 +14,10 @@ import MVMCore // MARK: - Properties //-------------------------------------------------- - public class var identifier: String { - return "listItem" - } + public class var identifier: String { "listItem" } public var molecule: MoleculeModelProtocol - + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- @@ -42,13 +39,13 @@ import MVMCore //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- - + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) molecule = try typeContainer.decodeModel(codingKey: .molecule) try super.init(from: decoder) } - + public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItem.swift b/MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItem.swift index 279e7948..43e2beda 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItem.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItem.swift @@ -11,6 +11,6 @@ import UIKit open class MoleculeStackItem: MoleculeContainer { var stackItemModel: StackItemModel? { - get { return model as? StackItemModel } + model as? StackItemModel } } diff --git a/MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItemModel.swift index ee2a2790..b5c42984 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/MoleculeStackItemModel.swift @@ -12,9 +12,7 @@ // MARK: - Properties //-------------------------------------------------- - public override class var identifier: String { - return "stackItem" - } + public override class var identifier: String { "stackItem" } public var spacing: CGFloat? public var percent: Int? public var gone: Bool = false diff --git a/MVMCoreUI/Atomic/Molecules/Items/MoleculeTableViewCell.swift b/MVMCoreUI/Atomic/Molecules/Items/MoleculeTableViewCell.swift index 666996d9..19e70358 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/MoleculeTableViewCell.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/MoleculeTableViewCell.swift @@ -30,16 +30,14 @@ import UIKit } public override class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { - return MoleculeContainer.nameForReuse(with: model, delegateObject) + MoleculeContainer.nameForReuse(with: model, delegateObject) } public override class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { - return MoleculeContainer.requiredModules(with: model, delegateObject, error: error) + MoleculeContainer.requiredModules(with: model, delegateObject, error: error) } public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - guard let height = MoleculeContainer.estimatedHeight(with: model, delegateObject) - else { return 80 } - return height + MoleculeContainer.estimatedHeight(with: model, delegateObject) ?? 80 } } diff --git a/MVMCoreUI/Atomic/Molecules/Items/StackItem.swift b/MVMCoreUI/Atomic/Molecules/Items/StackItem.swift index 61d63067..649eb2bf 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/StackItem.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/StackItem.swift @@ -8,7 +8,11 @@ open class StackItem: Container { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + var stackItemModel: StackItemModel? { - get { return model as? StackItemModel } + model as? StackItemModel } } diff --git a/MVMCoreUI/Atomic/Molecules/Items/StackItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/StackItemModel.swift index 69fe570d..6fa8b6fa 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/StackItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/StackItemModel.swift @@ -6,7 +6,6 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers public class StackItemModel: ContainerModel, StackItemModelProtocol, MoleculeModelProtocol { //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Molecules/Items/StackItemModelProtocol.swift b/MVMCoreUI/Atomic/Molecules/Items/StackItemModelProtocol.swift index 2223ed39..c3670c20 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/StackItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/StackItemModelProtocol.swift @@ -6,7 +6,6 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation public protocol StackItemModelProtocol { var spacing: CGFloat? { get set } diff --git a/MVMCoreUI/Atomic/Molecules/Items/TabsListItemModel.swift b/MVMCoreUI/Atomic/Molecules/Items/TabsListItemModel.swift index d0f13c1f..397cf613 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/TabsListItemModel.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/TabsListItemModel.swift @@ -8,17 +8,30 @@ import UIKit + public class TabsListItemModel: ListItemModel, MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "tabsListItem" var tabs: TabsModel var molecules: [[ListItemModelProtocol & MoleculeModelProtocol]] + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case tabs case molecules } + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + public override func setDefaults() { super.setDefaults() hideArrow = true @@ -28,19 +41,27 @@ public class TabsListItemModel: ListItemModel, MoleculeModelProtocol { bottomPadding = 0 } + //-------------------------------------------------- + // MARK: - Init + //-------------------------------------------------- + public init(with tabs: TabsModel, molecules: [[ListItemModelProtocol & MoleculeModelProtocol]]) { self.tabs = tabs self.molecules = molecules super.init() } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) tabs = try typeContainer.decode(TabsModel.self, forKey: .tabs) molecules = try typeContainer.decodeModels2D(codingKey: .molecules) try super.init(from: decoder) } - + public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Atomic/Molecules/Items/TabsTableViewCell.swift b/MVMCoreUI/Atomic/Molecules/Items/TabsTableViewCell.swift index 05ab4d29..bbad9823 100644 --- a/MVMCoreUI/Atomic/Molecules/Items/TabsTableViewCell.swift +++ b/MVMCoreUI/Atomic/Molecules/Items/TabsTableViewCell.swift @@ -49,9 +49,7 @@ import UIKit tabs.reset() } - public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - return 46 - } + public override class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { 46 } } extension TabsTableViewCell: TabsDelegate { diff --git a/MVMCoreUI/Atomic/Molecules/OtherContainers/BGImageMoleculeModel.swift b/MVMCoreUI/Atomic/Molecules/OtherContainers/BGImageMoleculeModel.swift index 56b77e3e..1b152f17 100644 --- a/MVMCoreUI/Atomic/Molecules/OtherContainers/BGImageMoleculeModel.swift +++ b/MVMCoreUI/Atomic/Molecules/OtherContainers/BGImageMoleculeModel.swift @@ -6,14 +6,20 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation open class BGImageMoleculeModel: MoleculeContainerModel { - open override class var identifier: String { - return "bgImageContainer" - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + open override class var identifier: String { "bgImageContainer" } + public var image: ImageViewModel + //-------------------------------------------------- + // MARK: - Methods + //-------------------------------------------------- + open override func setDefaults() { if useHorizontalMargins == nil { useHorizontalMargins = true @@ -35,15 +41,27 @@ open class BGImageMoleculeModel: MoleculeContainerModel { } } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case image } + + //-------------------------------------------------- + // MARK: - Initialization + //-------------------------------------------------- public init(_ image: ImageViewModel, molecule: MoleculeModelProtocol) { self.image = image super.init(with: molecule) } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) image = try typeContainer.decode(ImageViewModel.self, forKey:.image) diff --git a/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMolecule.swift b/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMolecule.swift index 21b68780..ce76d379 100644 --- a/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMolecule.swift +++ b/MVMCoreUI/Atomic/Molecules/OtherContainers/ModuleMolecule.swift @@ -12,7 +12,7 @@ open class ModuleMolecule: Container { open var moduleMolecule: MoleculeViewProtocol? var moduleMoleculeModel: ModuleMoleculeModel? { - get { return model as? ModuleMoleculeModel } + get { model as? ModuleMoleculeModel } } public override func setupView() { diff --git a/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerModel.swift b/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerModel.swift index 5ddec277..735e95c1 100644 --- a/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerModel.swift +++ b/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerModel.swift @@ -6,12 +6,13 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation open class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtocol, MoleculeModelProtocol { - open class var identifier: String { - return "container" - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + open class var identifier: String { "container" } public var backgroundColor: Color? public var molecule: MoleculeModelProtocol @@ -19,6 +20,10 @@ open class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtoco return [molecule] } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case molecule diff --git a/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerProtocol.swift b/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerProtocol.swift index 1e34932f..84b1f38e 100644 --- a/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerProtocol.swift +++ b/MVMCoreUI/Atomic/Molecules/OtherContainers/MoleculeContainerProtocol.swift @@ -6,7 +6,6 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation public protocol MoleculeContainerModelProtocol: ContainerModelProtocol, ParentMoleculeModelProtocol { var molecule: MoleculeModelProtocol { get set } diff --git a/MVMCoreUI/Atomic/Molecules/OtherContainers/ScrollerModel.swift b/MVMCoreUI/Atomic/Molecules/OtherContainers/ScrollerModel.swift index 697556b5..b6bc5586 100644 --- a/MVMCoreUI/Atomic/Molecules/OtherContainers/ScrollerModel.swift +++ b/MVMCoreUI/Atomic/Molecules/OtherContainers/ScrollerModel.swift @@ -9,8 +9,6 @@ import UIKit public class ScrollerModel: MoleculeContainerModel { - public override class var identifier: String { - return "scroller" - } + public override class var identifier: String { "scroller" } public var moleculeName: String = ScrollerModel.identifier } diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift index 6556796b..b1b12a54 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeModel.swift @@ -6,21 +6,32 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation public class StringAndMoleculeModel: MoleculeModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public static var identifier: String = "stringAndMoleculeModel" public var backgroundColor: Color? public var string: String public var molecule: MoleculeModelProtocol public var stringColor: Color + //-------------------------------------------------- + // MARK: - Init + //-------------------------------------------------- + public init(string: String, molecule: MoleculeModelProtocol, stringColor: Color = Color(uiColor: .mvmBlack)) { self.string = string self.molecule = molecule self.stringColor = stringColor } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case moleculeName case backgroundColor @@ -29,6 +40,10 @@ public class StringAndMoleculeModel: MoleculeModelProtocol { case stringColor } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + public required init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeStack.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeStack.swift index 35c3218e..42d941f7 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeStack.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeStack.swift @@ -14,8 +14,8 @@ open class StringAndMoleculeStack: MoleculeStackView { override open func createStackItemsFromModel(_ model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { guard let model = model as? StackModelProtocol, - let molcules = model.molecules as? [MoleculeStackItemModel] - else { return } + let molcules = model.molecules as? [MoleculeStackItemModel] + else { return } for stackItemModel in molcules { guard let stringAndMoleculeModel = stackItemModel.molecule as? StringAndMoleculeModel, diff --git a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeView.swift b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeView.swift index a9fd5da8..f590f3ba 100644 --- a/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeView.swift +++ b/MVMCoreUI/Atomic/Molecules/VerticalCombinationViews/Lists/StringAndMoleculeStack/StringAndMoleculeView.swift @@ -8,6 +8,9 @@ open class StringAndMoleculeView: View { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- var label = Label(fontStyle: .RegularBodySmall) var molecule: MoleculeViewProtocol @@ -25,7 +28,10 @@ open class StringAndMoleculeView: View { } } + //-------------------------------------------------- // MARK: - Inits + //-------------------------------------------------- + public init(string: String, molecule: MoleculeViewProtocol) { self.label.text = string self.molecule = molecule @@ -43,6 +49,10 @@ open class StringAndMoleculeView: View { super.init(model: model, delegateObject, additionalData) } + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + override public func setupView() { super.setupView() diff --git a/MVMCoreUI/Atomic/Organisms/Stack.swift b/MVMCoreUI/Atomic/Organisms/Stack.swift index dcdc31df..1f35e34d 100644 --- a/MVMCoreUI/Atomic/Organisms/Stack.swift +++ b/MVMCoreUI/Atomic/Organisms/Stack.swift @@ -16,7 +16,7 @@ open class Stack: Container where T: (StackModelProtocol & MoleculeModelProto open var stackItems: [UIView] = [] open var stackModel: T? { - get { model as? T } + model as? T } //-------------------------------------------------- diff --git a/MVMCoreUI/Atomic/Organisms/StackModel.swift b/MVMCoreUI/Atomic/Organisms/StackModel.swift index 8b1dcc0f..a350da63 100644 --- a/MVMCoreUI/Atomic/Organisms/StackModel.swift +++ b/MVMCoreUI/Atomic/Organisms/StackModel.swift @@ -15,9 +15,7 @@ static let defaultSpacing: CGFloat = 16.0 - public class var identifier: String { - return "stack" - } + public class var identifier: String { "stack" } public var backgroundColor: Color? public var molecules: [StackItemModelProtocol & MoleculeModelProtocol] diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift index 2ed2ca5a..afc5133c 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/CarouselItemModelProtocol.swift @@ -6,8 +6,6 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -import Foundation - public protocol CarouselItemModelProtocol: ContainerModelProtocol { var analyticsData: JSONValueDictionary? { get set } @@ -17,8 +15,9 @@ public protocol CarouselItemModelProtocol: ContainerModelProtocol { public extension CarouselItemModelProtocol { var analyticsData: JSONValueDictionary? { - get { return nil } + get { nil } set { analyticsData = newValue } } - func formFieldValue() -> AnyHashable? { return nil } + + func formFieldValue() -> AnyHashable? { nil } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ListItemModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ListItemModelProtocol.swift index b13ff039..3c64fdb4 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ListItemModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ListItemModelProtocol.swift @@ -6,7 +6,6 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -import Foundation public enum ListItemStyle: String, Codable { case standard @@ -27,12 +26,12 @@ public protocol ListItemModelProtocol: ContainerModelProtocol { public extension ListItemModelProtocol { var action: ActionModelProtocol? { - get { return nil } + get { nil } set { } } var style: ListItemStyle? { - get { return nil } + get { nil } set { } } } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift index 0cd54170..df3b0dca 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/MoleculeModelProtocol.swift @@ -1,5 +1,3 @@ -import Foundation - public enum MolecularError: Swift.Error { case error(String) diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/PageModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PageModelProtocol.swift index 275b17a1..cfad22df 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/PageModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/PageModelProtocol.swift @@ -6,7 +6,6 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation public protocol PageModelProtocol { var pageType: String { get set } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift index 1f9db75b..531a48d1 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/TemplateModelProtocol.swift @@ -6,8 +6,6 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -import Foundation - public protocol TemplateModelProtocol: PageModelProtocol, ModelProtocol, MoleculeTreeTraversalProtocol { var template: String { get } diff --git a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ThreeLayerTemplateModelProtocol.swift b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ThreeLayerTemplateModelProtocol.swift index 3f05a1e5..f15a1e7e 100644 --- a/MVMCoreUI/Atomic/Protocols/ModelProtocols/ThreeLayerTemplateModelProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/ModelProtocols/ThreeLayerTemplateModelProtocol.swift @@ -6,7 +6,6 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation public protocol ThreeLayerTemplateModelProtocol: TemplateModelProtocol { var anchorHeader: Bool { get set } diff --git a/MVMCoreUI/Atomic/Protocols/MoleculeViewProtocol.swift b/MVMCoreUI/Atomic/Protocols/MoleculeViewProtocol.swift index 57013638..b0e6b01c 100644 --- a/MVMCoreUI/Atomic/Protocols/MoleculeViewProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/MoleculeViewProtocol.swift @@ -9,14 +9,15 @@ import UIKit import MVMCore.MVMCoreViewProtocol + public protocol MoleculeViewProtocol: UIView, ModelHandlerProtocol { /// Initializes the view with the model init(model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) - + /// Sets the view with the model. func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) - + /// Resets to default state before set with json is called again. func reset() @@ -40,19 +41,17 @@ extension MoleculeViewProtocol { /// Uses moleculeName public static func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { - return model.moleculeName + model.moleculeName } - + // Do nothing, optionals. public func set(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { } + public func reset() { } - - public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - return nil - } - public static func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { - return nil - } + + public static func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { nil } + + public static func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { nil } /// Temporary convenience function for helping bridge the gap for legacy code. public func setOptional(with model: T?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { diff --git a/MVMCoreUI/Atomic/Protocols/TemplateProtocol.swift b/MVMCoreUI/Atomic/Protocols/TemplateProtocol.swift index 9a7e9e33..3d1bea9c 100644 --- a/MVMCoreUI/Atomic/Protocols/TemplateProtocol.swift +++ b/MVMCoreUI/Atomic/Protocols/TemplateProtocol.swift @@ -31,7 +31,7 @@ public extension TemplateProtocol where Self: ViewController { } func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> TemplateModel { - return try decoder.decode(TemplateModel.self, from: data) + try decoder.decode(TemplateModel.self, from: data) } /// Traverses all models and adds any required behavior models. diff --git a/MVMCoreUI/Atomic/Templates/CollectionTemplate.swift b/MVMCoreUI/Atomic/Templates/CollectionTemplate.swift index 8e0310a7..0d33d57f 100644 --- a/MVMCoreUI/Atomic/Templates/CollectionTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/CollectionTemplate.swift @@ -6,16 +6,19 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation @objc open class CollectionTemplate: ThreeLayerCollectionViewController, TemplateProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public typealias TemplateModel = CollectionTemplateModel public var templateModel: CollectionTemplateModel? public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: (CollectionItemModelProtocol & MoleculeModelProtocol))]? var observer: NSKeyValueObservation? - + //-------------------------------------------------- // MARK: - Computed Properties //-------------------------------------------------- @@ -68,9 +71,9 @@ import Foundation // This template requires atleast one of the three layers. if templateModel?.header == nil, - templateModel?.molecules?.count ?? 0 == 0, - templateModel?.footer == nil, - let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), messageToLog: "Collection template requires atleast one of the following: header, footer, molecules", code: CoreUIErrorCode.ErrorCodeListMolecule.rawValue, domain: ErrorDomainNative, location: String(describing: self)) { + templateModel?.molecules?.count ?? 0 == 0, + templateModel?.footer == nil, + let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), messageToLog: "Collection template requires atleast one of the following: header, footer, molecules", code: CoreUIErrorCode.ErrorCodeListMolecule.rawValue, domain: ErrorDomainNative, location: String(describing: self)) { error.pointee = errorObject return false } @@ -95,8 +98,8 @@ import Foundation // Update the width for columns. if let collectionView = collectionView, - let columns = templateModel?.columns, columns > 0, - let cell = cell as? CollectionTemplateItemProtocol { + let columns = templateModel?.columns, columns > 0, + let cell = cell as? CollectionTemplateItemProtocol { let width = (size - collectionView.adjustedContentInset.left - collectionView.adjustedContentInset.right) / CGFloat(columns) cell.set(width: width) } @@ -110,18 +113,16 @@ import Foundation collectionView?.register(moleculeInfo.class, forCellWithReuseIdentifier: moleculeInfo.identifier) } } - + open override func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { - return moleculesInfo?.count ?? 0 + moleculesInfo?.count ?? 0 } - - open override func numberOfSections(in collectionView: UICollectionView) -> Int { - return 1 - } - + + open override func numberOfSections(in collectionView: UICollectionView) -> Int { 1 } + open override func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { - guard let moleculeInfo = moleculesInfo?[indexPath.row] - else { return UICollectionViewCell() } + guard let moleculeInfo = moleculesInfo?[indexPath.row] else { return UICollectionViewCell() } + let cell = collectionView.dequeueReusableCell(withReuseIdentifier: moleculeInfo.identifier, for: indexPath) (cell as? MoleculeViewProtocol)?.reset() (cell as? MoleculeViewProtocol)?.set(with: moleculeInfo.molecule, delegateObjectIVar, nil) diff --git a/MVMCoreUI/Atomic/Templates/CollectionTemplateItemProtocol.swift b/MVMCoreUI/Atomic/Templates/CollectionTemplateItemProtocol.swift index 4e9ae26d..a11ff0b3 100644 --- a/MVMCoreUI/Atomic/Templates/CollectionTemplateItemProtocol.swift +++ b/MVMCoreUI/Atomic/Templates/CollectionTemplateItemProtocol.swift @@ -6,7 +6,6 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation /// A protocol that items of the CollectionTemplate must conform to. public protocol CollectionTemplateItemProtocol: UICollectionViewCell { @@ -26,11 +25,10 @@ public protocol CollectionTemplateItemProtocol: UICollectionViewCell { // Default implementation does nothing extension CollectionTemplateItemProtocol { - public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {} - - public func willDisplay() {} - public func shouldSelect(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Bool { - return false - } + public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { } + + public func willDisplay() { } + + public func shouldSelect(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Bool { false } } diff --git a/MVMCoreUI/Atomic/Templates/CollectionTemplateModel.swift b/MVMCoreUI/Atomic/Templates/CollectionTemplateModel.swift index b0f3ae92..fc71921e 100644 --- a/MVMCoreUI/Atomic/Templates/CollectionTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/CollectionTemplateModel.swift @@ -6,16 +6,13 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers public class CollectionTemplateModel: ThreeLayerModelBase { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public override class var identifier: String { - return "collection" - } + public override class var identifier: String { "collection" } public var molecules: [CollectionItemModelProtocol & MoleculeModelProtocol]? public var columns: Int? @@ -35,7 +32,7 @@ import Foundation self.screenHeading = screenHeading self.molecules = molecules } - + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- @@ -44,7 +41,7 @@ import Foundation case molecules case columns } - + //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- @@ -55,7 +52,7 @@ import Foundation columns = try typeContainer.decodeIfPresent(Int.self, forKey: .columns) try super.init(from: decoder) } - + public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) @@ -63,4 +60,3 @@ import Foundation try container.encodeIfPresent(columns, forKey: .columns) } } - diff --git a/MVMCoreUI/Atomic/Templates/ListPageTemplateModel.swift b/MVMCoreUI/Atomic/Templates/ListPageTemplateModel.swift index 44868e10..4796bed7 100644 --- a/MVMCoreUI/Atomic/Templates/ListPageTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/ListPageTemplateModel.swift @@ -6,19 +6,18 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers open class ListPageTemplateModel: ThreeLayerModelBase { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - open override class var identifier: String { - return "list" - } + open override class var identifier: String { "list" } + public var molecules: [ListItemModelProtocol & MoleculeModelProtocol]? public var line: LineModel? public var scrollToRowIndex: Int? + public var singleCellSelection: Bool = false public override var rootMolecules: [MoleculeModelProtocol] { if let molecules = molecules { @@ -30,12 +29,12 @@ import Foundation /// This template requires content. func validateModelHasContent() throws { if header == nil, - molecules?.count ?? 0 == 0, - footer == nil { + molecules?.count ?? 0 == 0, + footer == nil { throw ModelRegistry.Error.decoderOther(message: "List template requires atleast one of the following: header, footer, molecules") } } - + //-------------------------------------------------- // MARK: - Initializer //-------------------------------------------------- @@ -45,7 +44,7 @@ import Foundation self.screenHeading = screenHeading self.molecules = molecules } - + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- @@ -54,8 +53,9 @@ import Foundation case molecules case line case scrollToRowIndex + case singleCellSelection } - + //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- @@ -65,16 +65,19 @@ import Foundation molecules = try typeContainer.decodeModelsIfPresent(codingKey: .molecules) line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) scrollToRowIndex = try typeContainer.decodeIfPresent(Int.self, forKey: .scrollToRowIndex) + if let singleCellSelection = try typeContainer.decodeIfPresent(Bool.self, forKey: .singleCellSelection) { + self.singleCellSelection = singleCellSelection + } try super.init(from: decoder) try validateModelHasContent() } - + open override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeModelsIfPresent(molecules, forKey: .molecules) try container.encode(line, forKey: .line) + try container.encode(singleCellSelection, forKey: .singleCellSelection) try container.encodeIfPresent(scrollToRowIndex, forKey: .scrollToRowIndex) } } - diff --git a/MVMCoreUI/Atomic/Templates/ModalListPageTemplateModel.swift b/MVMCoreUI/Atomic/Templates/ModalListPageTemplateModel.swift index 64168e88..9459aab6 100644 --- a/MVMCoreUI/Atomic/Templates/ModalListPageTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/ModalListPageTemplateModel.swift @@ -6,19 +6,16 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers open class ModalListPageTemplateModel: ListPageTemplateModel { //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - open override class var identifier: String { - return "modalList" - } + open override class var identifier: String { "modalList" } public var closeAction: ActionModelProtocol? - + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- @@ -26,21 +23,20 @@ import Foundation private enum CodingKeys: String, CodingKey { case closeAction } - + //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- - + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) closeAction = try typeContainer.decodeModelIfPresent(codingKey: .closeAction) try super.init(from: decoder) } - + open override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeModelIfPresent(closeAction, forKey: .closeAction) } } - diff --git a/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift index 1a82333d..71c23c16 100644 --- a/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ModalMoleculeListTemplate.swift @@ -15,14 +15,14 @@ open class ModalMoleculeListTemplate: MoleculeListTemplate { //-------------------------------------------------- public var closeButton: Button? - + //-------------------------------------------------- // MARK: - Lifecycle //-------------------------------------------------- // For subclassing the model. open override func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> ModalListPageTemplateModel { - return try decoder.decode(ModalListPageTemplateModel.self, from: data) + try decoder.decode(ModalListPageTemplateModel.self, from: data) } override open func handleNewData() { diff --git a/MVMCoreUI/Atomic/Templates/ModalMoleculeStackTemplate.swift b/MVMCoreUI/Atomic/Templates/ModalMoleculeStackTemplate.swift index 1db1bb9c..1c76b467 100644 --- a/MVMCoreUI/Atomic/Templates/ModalMoleculeStackTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ModalMoleculeStackTemplate.swift @@ -9,15 +9,22 @@ import UIKit open class ModalMoleculeStackTemplate: MoleculeStackTemplate { + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- // For subclassing the model. open override func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> ModalStackPageTemplateModel { - return try decoder.decode(ModalStackPageTemplateModel.self, from: data) + try decoder.decode(ModalStackPageTemplateModel.self, from: data) } + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + override open func handleNewData() { super.handleNewData() - _ = MVMCoreUICommonViewsUtility.addCloseButton(to: view, action: {[weak self] _ in + _ = MVMCoreUICommonViewsUtility.addCloseButton(to: view, action: { [weak self] _ in guard let self = self else { return } let closeAction = (self.templateModel as? ModalStackPageTemplateModel)?.closeAction ?? ActionBackModel() diff --git a/MVMCoreUI/Atomic/Templates/ModalSectionListTemplate.swift b/MVMCoreUI/Atomic/Templates/ModalSectionListTemplate.swift index 424fc6c5..3e4f3fc2 100644 --- a/MVMCoreUI/Atomic/Templates/ModalSectionListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ModalSectionListTemplate.swift @@ -6,18 +6,24 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation open class ModalSectionListTemplate: SectionListTemplate { + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- // For subclassing the model. open override func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> ModalSectionListTemplateModel { - return try decoder.decode(ModalSectionListTemplateModel.self, from: data) + try decoder.decode(ModalSectionListTemplateModel.self, from: data) } + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + override open func handleNewData() { super.handleNewData() - _ = MVMCoreUICommonViewsUtility.addCloseButton(to: view, action: {[weak self] _ in + _ = MVMCoreUICommonViewsUtility.addCloseButton(to: view, action: { [weak self] _ in guard let self = self else { return } let closeAction = (self.templateModel as? ModalSectionListTemplateModel)?.closeAction ?? ActionBackModel() diff --git a/MVMCoreUI/Atomic/Templates/ModalSectionListTemplateModel.swift b/MVMCoreUI/Atomic/Templates/ModalSectionListTemplateModel.swift index 83f2bb98..d0f4d456 100644 --- a/MVMCoreUI/Atomic/Templates/ModalSectionListTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/ModalSectionListTemplateModel.swift @@ -6,24 +6,37 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers public class ModalSectionListTemplateModel: SectionListTemplateModel { - public override class var identifier: String { - return "modalSectionList" - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public override class var identifier: String { "modalSectionList" } public var closeAction: ActionModelProtocol? + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case closeAction } - + + //-------------------------------------------------- + // MARK: - Init + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) closeAction = try typeContainer.decodeModelIfPresent(codingKey: .closeAction) try super.init(from: decoder) } - + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Atomic/Templates/ModalStackPageTemplateModel.swift b/MVMCoreUI/Atomic/Templates/ModalStackPageTemplateModel.swift index 4e878595..3e8d2363 100644 --- a/MVMCoreUI/Atomic/Templates/ModalStackPageTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/ModalStackPageTemplateModel.swift @@ -6,24 +6,37 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers public class ModalStackPageTemplateModel: StackPageTemplateModel { - public override class var identifier: String { - return "modalStack" - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public override class var identifier: String { "modalStack" } public var closeAction: ActionModelProtocol? + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case closeAction } - + + //-------------------------------------------------- + // MARK: - Init + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) closeAction = try typeContainer.decodeModelIfPresent(codingKey: .closeAction) try super.init(from: decoder) } - + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListCellProtocol.swift b/MVMCoreUI/Atomic/Templates/MoleculeListCellProtocol.swift index 46c9a0fa..51688330 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListCellProtocol.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListCellProtocol.swift @@ -6,25 +6,34 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation public protocol MoleculeListCellProtocol: UITableViewCell { /// Can set the separator according to what the moleculeList commands. func setLines(with model: LineModel?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, indexPath: IndexPath) + /// Handle action when cell is pressed + func willSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Bool + /// Handle action when cell is pressed func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) - + + /// Handle action when cell is deselected. + func didDeselectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) + /// Called by the list when the cell will display. func willDisplay() } // Default implementation does nothing -extension MoleculeListCellProtocol { +public extension MoleculeListCellProtocol { - public func setLines(with model: LineModel?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, indexPath: IndexPath) { } + func setLines(with model: LineModel?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, indexPath: IndexPath) { } - public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { } + func willSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Bool { true } + + func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { } + + func didDeselectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { } func willDisplay() { } } diff --git a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift index bb2eeb94..34f81bc4 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeListTemplate.swift @@ -8,13 +8,15 @@ import UIKit +public typealias MoleculeInfo = (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol) + open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol { //-------------------------------------------------- // MARK: - Stored Properties //-------------------------------------------------- - public var moleculesInfo: [(identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)]? + public var moleculesInfo: [MoleculeInfo]? var observer: NSKeyValueObservation? @@ -38,6 +40,10 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } } + open var hasSingleCellSelection: Bool { + templateModel?.singleCellSelection ?? false + } + //-------------------------------------------------- // MARK: - Methods //-------------------------------------------------- @@ -49,7 +55,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol // For subclassing the model. open func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> ListPageTemplateModel { - return try decoder.decode(ListPageTemplateModel.self, from: data) + try decoder.decode(ListPageTemplateModel.self, from: data) } open override func viewForTop() -> UIView { @@ -83,19 +89,20 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol open override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) - //Handle scroll handleScrollToSpecificRow() } - //-------------------------------------------------- // MARK: - Handle scroll to spefic row //-------------------------------------------------- + func handleScrollToSpecificRow() { guard let index = templateModel?.scrollToRowIndex, loadObject?.pageDataFromCache == false, let table = tableView, - index < tableView(table, numberOfRowsInSection:0) else { return } + index < tableView(table, numberOfRowsInSection:0) + else { return } + let indexPath = IndexPath(row: index, section: 0) tableView?.scrollToRow(at: indexPath, at: .middle, animated: false) //Reset for without refresh page not needed @@ -124,7 +131,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return moleculesInfo?.count ?? 0 + moleculesInfo?.count ?? 0 } open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { @@ -146,10 +153,29 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol (cell as? MoleculeListCellProtocol)?.willDisplay() } - open func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - if let cell = tableView.cellForRow(at: indexPath) as? MoleculeListCellProtocol { - cell.didSelectCell(at: indexPath, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil) - } + open func tableView(_ tableView: UITableView, willSelectRowAt indexPath: IndexPath) -> IndexPath? { + guard let cell = tableView.cellForRow(at: indexPath) as? MoleculeListCellProtocol, + !cell.willSelectCell(at: indexPath, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil) + else { return indexPath } + + return nil + } + + open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + guard let cell = tableView.cellForRow(at: indexPath) as? MoleculeListCellProtocol else { return } + + cell.didSelectCell(at: indexPath, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil) + } + + open override func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { + guard let cell = tableView.cellForRow(at: indexPath) as? MoleculeListCellProtocol else { return } + + cell.didDeselectCell(at: indexPath, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil) + } + + func performTableViewUpdates() { + tableView.beginUpdates() + tableView.endUpdates() } //-------------------------------------------------- @@ -157,13 +183,11 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol //-------------------------------------------------- open override func moleculeLayoutUpdated(_ molecule: MoleculeViewProtocol) { + guard let tableView = tableView else { return } - if let tableView = tableView { - let point = molecule.convert(molecule.bounds.origin, to: tableView) - if let indexPath = tableView.indexPathForRow(at: point), tableView.indexPathsForVisibleRows?.contains(indexPath) ?? false { - tableView.beginUpdates() - tableView.endUpdates() - } + let point = molecule.convert(molecule.bounds.origin, to: tableView) + if let indexPath = tableView.indexPathForRow(at: point), tableView.indexPathsForVisibleRows?.contains(indexPath) ?? false { + performTableViewUpdates() } } @@ -173,6 +197,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol let json = moleculeInfo.molecule.toJSON() return json == molecule.toJSON() }) else { return nil } + return IndexPath(row: index, section: 0) } @@ -219,7 +244,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol //-------------------------------------------------- /// Returns the (identifier, class) of the molecule for the given model. - func createMoleculeInfo(with listItem: MoleculeModelProtocol?) -> (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)? { + func createMoleculeInfo(with listItem: MoleculeModelProtocol?) -> MoleculeInfo? { guard let listItem = listItem, let moleculeClass = ModelRegistry.getMoleculeClass(listItem) @@ -231,14 +256,14 @@ open class MoleculeListTemplate: ThreeLayerTableViewController, TemplateProtocol } /// Returns the (identifier, class) of the molecule for the indexPath. - func getMoleculeInfo(for indexPath: IndexPath) -> (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)? { - return moleculesInfo?[indexPath.row] + func getMoleculeInfo(for indexPath: IndexPath) -> MoleculeInfo? { + moleculesInfo?[indexPath.row] } /// Sets up the molecule list and ensures no errors loading all content. - func getMoleculeInfoList() -> [(identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)]? { + func getMoleculeInfoList() -> [MoleculeInfo]? { - var moleculeList: [(identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)] = [] + var moleculeList: [MoleculeInfo] = [] if let molecules = templateModel?.molecules { for molecule in molecules { diff --git a/MVMCoreUI/Atomic/Templates/MoleculeStackCenteredTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeStackCenteredTemplate.swift index af5af39c..b3448827 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeStackCenteredTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeStackCenteredTemplate.swift @@ -8,8 +8,11 @@ import UIKit + public class MoleculeStackCenteredTemplate: MoleculeStackTemplate { - public override func spaceBetweenTopAndMiddle() -> CGFloat? { - return nil - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public override func spaceBetweenTopAndMiddle() -> CGFloat? { nil } } diff --git a/MVMCoreUI/Atomic/Templates/MoleculeStackTemplate.swift b/MVMCoreUI/Atomic/Templates/MoleculeStackTemplate.swift index 957b1bd9..046469a8 100644 --- a/MVMCoreUI/Atomic/Templates/MoleculeStackTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/MoleculeStackTemplate.swift @@ -51,9 +51,7 @@ open class MoleculeStackTemplate: ThreeLayerViewController, TemplateProtocol { } } - open override func spaceBetweenTopAndMiddle() -> CGFloat? { - return 0 - } + open override func spaceBetweenTopAndMiddle() -> CGFloat? { 0 } open override func viewForTop() -> UIView? { guard let headerModel = templateModel?.header, diff --git a/MVMCoreUI/Atomic/Templates/SectionListTemplate.swift b/MVMCoreUI/Atomic/Templates/SectionListTemplate.swift index bc12146f..08a7d020 100644 --- a/MVMCoreUI/Atomic/Templates/SectionListTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/SectionListTemplate.swift @@ -6,11 +6,10 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation open class SectionListTemplate: MoleculeListTemplate { - public var sectionMoleculesInfo: [(header: (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)?, footer: (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)?, rows: [(identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)])]? + public var sectionMoleculesInfo: [(header: MoleculeInfo?, footer: MoleculeInfo?, rows: [MoleculeInfo])]? open override func viewDidLoad() { super.viewDidLoad() @@ -19,13 +18,13 @@ open class SectionListTemplate: MoleculeListTemplate { override func setup() { // Create quick reference - var sectionList: [(header: (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)?, footer: (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)?, rows: [(identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)])] = [] + var sectionList: [(header: MoleculeInfo?, footer: MoleculeInfo?, rows: [MoleculeInfo])] = [] if let sections = (templateModel as? SectionListTemplateModel)?.sections { for section in sections { let header = createMoleculeInfo(with: section.header) let footer = createMoleculeInfo(with: section.footer) - var rows: [(identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)] = [] + var rows: [MoleculeInfo] = [] for row in section.rows { if let rowInfo = createMoleculeInfo(with: row) { rows.append(rowInfo) @@ -38,8 +37,8 @@ open class SectionListTemplate: MoleculeListTemplate { sectionMoleculesInfo = sectionList.count > 0 ? sectionList : nil } - override func getMoleculeInfo(for indexPath: IndexPath) -> (identifier: String, class: AnyClass, molecule: MoleculeModelProtocol)? { - return sectionMoleculesInfo?[indexPath.section].rows[indexPath.row] + override func getMoleculeInfo(for indexPath: IndexPath) -> MoleculeInfo? { + sectionMoleculesInfo?[indexPath.section].rows[indexPath.row] } open override func createTableView() -> TableView { @@ -54,7 +53,7 @@ open class SectionListTemplate: MoleculeListTemplate { // For subclassing the model. open override func decodeTemplate(using decoder: JSONDecoder, from data: Data) throws -> SectionListTemplateModel { - return try decoder.decode(SectionListTemplateModel.self, from: data) + try decoder.decode(SectionListTemplateModel.self, from: data) } open override func registerWithTable() { @@ -105,7 +104,9 @@ open class SectionListTemplate: MoleculeListTemplate { public func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { guard let sectionInfo = sectionMoleculesInfo?[section], - let headerInfo = sectionInfo.header else { return nil } + let headerInfo = sectionInfo.header + else { return nil } + let header = tableView.dequeueReusableHeaderFooterView(withIdentifier: headerInfo.identifier) (header as? MoleculeViewProtocol)?.reset() (header as? MoleculeViewProtocol)?.set(with: headerInfo.molecule, delegateObjectIVar, nil) @@ -117,7 +118,9 @@ open class SectionListTemplate: MoleculeListTemplate { public func tableView(_ tableView: UITableView, viewForFooterInSection section: Int) -> UIView? { guard let sectionInfo = sectionMoleculesInfo?[section], - let footerInfo = sectionInfo.footer else { return nil } + let footerInfo = sectionInfo.footer + else { return nil } + let footer = tableView.dequeueReusableHeaderFooterView(withIdentifier: footerInfo.identifier) (footer as? MoleculeViewProtocol)?.reset() (footer as? MoleculeViewProtocol)?.set(with: footerInfo.molecule, delegateObjectIVar, nil) @@ -128,10 +131,10 @@ open class SectionListTemplate: MoleculeListTemplate { } open override func getNumberOfSections() -> Int { - return sectionMoleculesInfo?.count ?? 0 + sectionMoleculesInfo?.count ?? 0 } open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return sectionMoleculesInfo?[section].rows.count ?? 0 + sectionMoleculesInfo?[section].rows.count ?? 0 } } diff --git a/MVMCoreUI/Atomic/Templates/SectionListTemplateModel.swift b/MVMCoreUI/Atomic/Templates/SectionListTemplateModel.swift index 280ea4e5..609e4cc0 100644 --- a/MVMCoreUI/Atomic/Templates/SectionListTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/SectionListTemplateModel.swift @@ -6,13 +6,15 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation -public protocol SectionListHeaderFooterModel { - -} +public protocol SectionListHeaderFooterModel { } + @objcMembers open class SectionModel: Codable { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public var header: (SectionListHeaderFooterModel & MoleculeModelProtocol)? public var footer: (SectionListHeaderFooterModel & MoleculeModelProtocol)? public var rows: [ListItemModelProtocol & MoleculeModelProtocol] @@ -26,18 +28,18 @@ public protocol SectionListHeaderFooterModel { case footer case rows } - + //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- - + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) header = try typeContainer.decodeModelIfPresent(codingKey: .header) footer = try typeContainer.decodeModelIfPresent(codingKey: .footer) rows = try typeContainer.decodeModels(codingKey: .rows) } - + open func encode(to encoder: Encoder) throws { var container = encoder.container(keyedBy: CodingKeys.self) try container.encodeModelIfPresent(header, forKey: .header) @@ -51,20 +53,18 @@ public protocol SectionListHeaderFooterModel { // MARK: - Properties //-------------------------------------------------- - open override class var identifier: String { - return "sectionList" - } + open override class var identifier: String { "sectionList" } public var sections: [SectionModel] override func validateModelHasContent() throws { if header == nil, - sections.count == 0, - footer == nil { + sections.count == 0, + footer == nil { throw ModelRegistry.Error.decoderOther(message: "Section List template requires atleast one of the following: header, footer, sections") } } - + //-------------------------------------------------- // MARK: - Keys //-------------------------------------------------- @@ -72,17 +72,17 @@ public protocol SectionListHeaderFooterModel { private enum CodingKeys: String, CodingKey { case sections } - + //-------------------------------------------------- // MARK: - Codec //-------------------------------------------------- - + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) sections = try typeContainer.decode([SectionModel].self, forKey: .sections) try super.init(from: decoder) } - + open override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Atomic/Templates/StackCenteredPageTemplateModel.swift b/MVMCoreUI/Atomic/Templates/StackCenteredPageTemplateModel.swift index 20d727e3..903523ab 100644 --- a/MVMCoreUI/Atomic/Templates/StackCenteredPageTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/StackCenteredPageTemplateModel.swift @@ -6,10 +6,11 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers public class StackCenteredPageTemplateModel: StackPageTemplateModel { - public override class var identifier: String { - return "stackCenterTemplate" - } + //-------------------------------------------------- + // MARK: - Property + //-------------------------------------------------- + + public override class var identifier: String { "stackCenterTemplate" } } diff --git a/MVMCoreUI/Atomic/Templates/StackPageTemplateModel.swift b/MVMCoreUI/Atomic/Templates/StackPageTemplateModel.swift index 6491bd8d..27769b20 100644 --- a/MVMCoreUI/Atomic/Templates/StackPageTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/StackPageTemplateModel.swift @@ -6,34 +6,46 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -import Foundation - @objcMembers public class StackPageTemplateModel: ThreeLayerModelBase { - public override class var identifier: String { - return "stack" - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public override class var identifier: String { "stack" } public var moleculeStack: StackModel public override var rootMolecules: [MoleculeModelProtocol] { return [header, moleculeStack, footer].compactMap { $0 } } + //-------------------------------------------------- + // MARK: - Init + //-------------------------------------------------- + public init(pageType: String, moleculeStack: StackModel) { self.moleculeStack = moleculeStack super.init(pageType: pageType) } - + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case stack } - + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) moleculeStack = try typeContainer.decode(StackModel.self, forKey: .stack) try super.init(from: decoder) } - + public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Atomic/Templates/TemplateModel.swift b/MVMCoreUI/Atomic/Templates/TemplateModel.swift index 94d6ee80..4f565e85 100644 --- a/MVMCoreUI/Atomic/Templates/TemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/TemplateModel.swift @@ -10,19 +10,16 @@ import Foundation @objcMembers open class TemplateModel: MVMControllerModelProtocol, TabPageModelProtocol { - //-------------------------------------------------- // MARK: - Properties //-------------------------------------------------- - public class var identifier: String { - return "" - } + public class var identifier: String { "" } public var pageType: String public var template: String { // Although this is done in the extension, it is needed for the encoding. - return Self.identifier + Self.identifier } public var backgroundColor: Color? diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplate.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplate.swift index 3d0119a9..4660141c 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplate.swift @@ -6,10 +6,11 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers open class ThreeLayerCenterTemplate: ThreeLayerTemplate { - open override func spaceBetweenTopAndMiddle() -> CGFloat? { - return nil - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + open override func spaceBetweenTopAndMiddle() -> CGFloat? { nil } } diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplateModel.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplateModel.swift index 4bea76f2..35a12870 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerCenterTemplateModel.swift @@ -6,10 +6,11 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers public class ThreeLayerCenterPageTemplateModel: ThreeLayerPageTemplateModel { - public override class var identifier: String { - return "threeLayerCenter" - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public override class var identifier: String { "threeLayerCenter" } } diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplate.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplate.swift index 81c3b6a8..eb8a674f 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplate.swift @@ -6,13 +6,17 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation - @objcMembers open class ThreeLayerFillMiddleTemplate: ThreeLayerTemplate { - open override func spaceBetweenMiddleAndBottom() -> CGFloat? { - return 0 - } + //-------------------------------------------------- + // MARK: - Spacing + //-------------------------------------------------- + + open override func spaceBetweenMiddleAndBottom() -> CGFloat? { 0 } + + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- open override func loadView() { super.loadView() diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplateModel.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplateModel.swift index 7ea1aa70..6f1b3077 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerFillMiddleTemplateModel.swift @@ -6,10 +6,11 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers public class ThreeLayerFillMiddleTemplateModel: ThreeLayerPageTemplateModel { - public override class var identifier: String { - return "threeLayerFillMiddle" - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public override class var identifier: String { "threeLayerFillMiddle" } } diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift index 25e7d1e9..6a1bb244 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerModelBase.swift @@ -6,9 +6,11 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers open class ThreeLayerModelBase: TemplateModel, ThreeLayerTemplateModelProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- public var anchorHeader: Bool = false public var header: MoleculeModelProtocol? @@ -19,17 +21,29 @@ import Foundation return [header, footer].compactMap { $0 } } + //-------------------------------------------------- + // MARK: - Init + //-------------------------------------------------- + public override init(pageType: String) { super.init(pageType: pageType) } + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- + private enum CodingKeys: String, CodingKey { case anchorHeader case header case anchorFooter case footer } - + + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) if let anchor = try typeContainer.decodeIfPresent(Bool.self, forKey: .anchorHeader) { @@ -42,7 +56,7 @@ import Foundation footer = try typeContainer.decodeModelIfPresent(codingKey: .footer) try super.init(from: decoder) } - + public override func encode(to encoder: Encoder) throws { try super.encode(to: encoder) var container = encoder.container(keyedBy: CodingKeys.self) diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerPageTemplateModel.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerPageTemplateModel.swift index ced0b9ab..e3ada79d 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerPageTemplateModel.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerPageTemplateModel.swift @@ -6,12 +6,13 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -import Foundation @objcMembers public class ThreeLayerPageTemplateModel: ThreeLayerModelBase { - public override class var identifier: String { - return "threeLayer" - } + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + + public override class var identifier: String { "threeLayer" } public var middle: MoleculeModelProtocol? public override var rootMolecules: [MoleculeModelProtocol] { @@ -21,17 +22,29 @@ import Foundation return super.rootMolecules } + //-------------------------------------------------- + // MARK: - Init + //-------------------------------------------------- + public init(pageType: String, header: MoleculeModelProtocol?, middle: MoleculeModelProtocol?, footer: MoleculeModelProtocol?) { super.init(pageType: pageType) self.header = header self.middle = middle self.footer = footer } + + //-------------------------------------------------- + // MARK: - Keys + //-------------------------------------------------- private enum CodingKeys: String, CodingKey { case middle } + //-------------------------------------------------- + // MARK: - Codec + //-------------------------------------------------- + required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) middle = try typeContainer.decodeModelIfPresent(codingKey: .middle) diff --git a/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift b/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift index 5da54946..502b269f 100644 --- a/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift +++ b/MVMCoreUI/Atomic/Templates/ThreeLayerTemplate.swift @@ -9,8 +9,16 @@ import UIKit @objcMembers open class ThreeLayerTemplate: ThreeLayerViewController, TemplateProtocol { + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public var templateModel: TemplateModel? + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + open override func parsePageJSON() throws { try parseTemplate(json: loadObject?.pageJSON) try super.parsePageJSON() @@ -46,11 +54,11 @@ import UIKit return molecule } - open override func spaceBetweenTopAndMiddle() -> CGFloat? { - return 0 - } + //-------------------------------------------------- + // MARK: - Spacing + //-------------------------------------------------- - open override func spaceBetweenMiddleAndBottom() -> CGFloat? { - return nil - } + open override func spaceBetweenTopAndMiddle() -> CGFloat? { 0 } + + open override func spaceBetweenMiddleAndBottom() -> CGFloat? { nil } } diff --git a/MVMCoreUI/BaseClasses/TableViewCell.swift b/MVMCoreUI/BaseClasses/TableViewCell.swift index c4c1f35c..d0bb9c7e 100644 --- a/MVMCoreUI/BaseClasses/TableViewCell.swift +++ b/MVMCoreUI/BaseClasses/TableViewCell.swift @@ -174,17 +174,11 @@ import UIKit // MARK: Overridables // Base classes need to implement these functions otherwise swift won't respect the subclass functions and use the ones in the protocol extension instead. - open class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { - return model.moleculeName - } + open class func nameForReuse(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> String? { model.moleculeName } - open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { - return nil - } + open class func estimatedHeight(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? { nil } - open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { - return nil - } + open class func requiredModules(with model: MoleculeModelProtocol, _ delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer?) -> [String]? { nil } // MARK: - Caret View /// Adds the standard mvm style caret to the accessory view @@ -244,7 +238,7 @@ import UIKit // MARK: - MoleculeListCellProtocol /// For when the separator between cells shows using json and frequency. Default is type: standard, frequency: allExceptTop. - public func setLines(with model: LineModel?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, indexPath: IndexPath) { + open func setLines(with model: LineModel?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, indexPath: IndexPath) { addSeparatorsIfNeeded() if let model = model { topSeparatorView?.set(with: model, delegateObject, additionalData) @@ -256,12 +250,16 @@ import UIKit setSeparatorFrequency(model?.frequency ?? .allExceptTop, indexPath: indexPath) } - public func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + open func willSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) -> Bool { true } + + open func didSelectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { guard let action = listItemModel?.action else { return } Button.performButtonAction(with: action, button: self, delegateObject: delegateObject, additionalData: additionalData) } - public func willDisplay() { + open func didDeselectCell(at index: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { } + + open func willDisplay() { _ = alignAccessoryToHero() } diff --git a/MVMCoreUI/BaseControllers/ProgrammaticScrollViewController.swift b/MVMCoreUI/BaseControllers/ProgrammaticScrollViewController.swift index 19c6f2b7..85d9cd95 100644 --- a/MVMCoreUI/BaseControllers/ProgrammaticScrollViewController.swift +++ b/MVMCoreUI/BaseControllers/ProgrammaticScrollViewController.swift @@ -6,12 +6,19 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation open class ProgrammaticScrollViewController: ScrollingViewController { + //-------------------------------------------------- + // MARK: - Constraints + //-------------------------------------------------- + public var topConstraint: NSLayoutConstraint? public var bottomConstraint: NSLayoutConstraint? + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + public override init(with scrollView: UIScrollView) { super.init(with: scrollView) } @@ -24,6 +31,10 @@ open class ProgrammaticScrollViewController: ScrollingViewController { super.init(coder: coder) } + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + open override func loadView() { let view = UIView() diff --git a/MVMCoreUI/BaseControllers/ProgrammaticTableViewController.swift b/MVMCoreUI/BaseControllers/ProgrammaticTableViewController.swift index 21f1de1e..211426c3 100644 --- a/MVMCoreUI/BaseControllers/ProgrammaticTableViewController.swift +++ b/MVMCoreUI/BaseControllers/ProgrammaticTableViewController.swift @@ -6,11 +6,18 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation open class ProgrammaticTableViewController: ProgrammaticScrollViewController, UITableViewDelegate, UITableViewDataSource { + //-------------------------------------------------- + // MARK: - Outlet + //-------------------------------------------------- + @IBOutlet public var tableView: TableView! + //-------------------------------------------------- + // MARK: - Initializers + //-------------------------------------------------- + public init(with tableView: TableView) { self.tableView = tableView super.init(with: tableView) @@ -24,9 +31,13 @@ open class ProgrammaticTableViewController: ProgrammaticScrollViewController, UI super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil) } + //-------------------------------------------------- + // MARK: - Lifecycle + //-------------------------------------------------- + open override func loadView() { let view = UIView() - view.backgroundColor = .white + view.backgroundColor = .mvmWhite let tableView = createTableView() tableView.translatesAutoresizingMaskIntoConstraints = false @@ -47,19 +58,23 @@ open class ProgrammaticTableViewController: ProgrammaticScrollViewController, UI registerWithTable() } + //-------------------------------------------------- + // MARK: - Table View + //-------------------------------------------------- + /// This class should create the table view that will be used here. Subclass this for different table styles. open func createTableView() -> TableView { let tableView = TableView(frame: .zero, style: .grouped) tableView.backgroundColor = .clear - tableView.separatorStyle = UITableViewCell.SeparatorStyle.none + tableView.separatorStyle = .none tableView.delegate = self tableView.dataSource = self tableView.insetsContentViewsToSafeArea = false return tableView } - // Registers classes and nibs. Can subclass for different nibs. Can call super and then add new ones after as well. - open func registerWithTable() {} + /// Registers classes and nibs. Can subclass for different nibs. Can call super and then add new ones after as well. + open func registerWithTable() { } /// Sets the table to have no section headers or footers. open func setNoSectionHeadersFooters() { @@ -73,19 +88,17 @@ open class ProgrammaticTableViewController: ProgrammaticScrollViewController, UI } /// For subclassing, returns the number of sections for table. This function calls numberOfSectionsForTableview aftre ensuring the table is setup properly. - open func getNumberOfSections() -> Int { - return 1 - } + open func getNumberOfSections() -> Int { 1 } open func numberOfSections(in tableView: UITableView) -> Int { - return tableView.bounds.width > 1 ? getNumberOfSections() : 0 + tableView.bounds.width > 1 ? getNumberOfSections() : 0 } - open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - return 0 - } + open func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 0 } - open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { - return UITableViewCell() - } + open func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { UITableViewCell() } + + open func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { } + + open func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { } } diff --git a/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift b/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift index 494599dc..37de809f 100644 --- a/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift +++ b/MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift @@ -11,17 +11,33 @@ import MVMAnimationFramework open class ThreeLayerTableViewController: ProgrammaticTableViewController { - // The three main views + //-------------------------------------------------- + // MARK: - Main Views + //-------------------------------------------------- + private var topView: UIView? private var bottomView: UIView? private var headerView: UIView? private var footerView: UIView? + + //-------------------------------------------------- + // MARK: - Properties + //-------------------------------------------------- + public var bottomViewOutsideOfScrollArea: Bool = false public var topViewOutsideOfScrollArea: Bool = false + + //-------------------------------------------------- + // MARK: - Constraints + //-------------------------------------------------- + private var topViewBottomConstraint: NSLayoutConstraint? private var bottomViewTopConstraint: NSLayoutConstraint? - //MARK: - MFViewController + //-------------------------------------------------- + // MARK: - MFViewController + //-------------------------------------------------- + open override func updateViews() { super.updateViews() let width = view.bounds.width @@ -54,23 +70,20 @@ open class ThreeLayerTableViewController: ProgrammaticTableViewController { self?.view.setNeedsUpdateConstraints() } } + + //-------------------------------------------------- + // MARK: - Spacing + //-------------------------------------------------- - //MARK: - Spacing // If both are subclassed to return a value, then the buttons will not be pinned towards the bottom because neither spacing would try to fill the screen. /// Space between the top view and the table sections, nil to fill. 0 default - open func spaceBelowTopView() -> CGFloat? { - return 0 - } + open func spaceBelowTopView() -> CGFloat? { 0 } /// Space between the bottom view and the table sections, nil to fill. nil default - open func spaceAboveBottomView() -> CGFloat? { - return nil - } + open func spaceAboveBottomView() -> CGFloat? { nil } /// can override to return a minimum fill space. - open func minimumFillSpace() -> CGFloat { - return 0 - } + open func minimumFillSpace() -> CGFloat { 0 } open override func updateViewConstraints() { guard let tableView = tableView else { @@ -126,7 +139,10 @@ open class ThreeLayerTableViewController: ProgrammaticTableViewController { super.updateViewConstraints() } - //MARK: - Header Footer + //-------------------------------------------------- + // MARK: - Header Footer + //-------------------------------------------------- + /// Gets the top view and adds it to a spacing view, headerView, and then calls showHeader. open func createViewForTableHeader() { var topView = viewForTop() @@ -228,17 +244,20 @@ open class ThreeLayerTableViewController: ProgrammaticTableViewController { tableView.tableFooterView = tableFooterView } - //MARK: - Functions to subclass + //-------------------------------------------------- + // MARK: - Functions to subclass + //-------------------------------------------------- + /// Subclass for a top view. open func viewForTop() -> UIView { // Small height is needed to stop apple from adding padding for grouped tables when no header. - return MVMCoreUICommonViewsUtility.getView(with: 0.5) + MVMCoreUICommonViewsUtility.getView(with: 0.5) } /// Subclass for a bottom view. open func viewForBottom() -> UIView { // Default spacing is standard when no buttons. - return MVMCoreUICommonViewsUtility.getView(with: PaddingDefaultVerticalSpacing) + MVMCoreUICommonViewsUtility.getView(with: PaddingDefaultVerticalSpacing) } deinit { diff --git a/MVMCoreUI/BaseControllers/ViewController.swift b/MVMCoreUI/BaseControllers/ViewController.swift index efb083a5..293bd49f 100644 --- a/MVMCoreUI/BaseControllers/ViewController.swift +++ b/MVMCoreUI/BaseControllers/ViewController.swift @@ -653,7 +653,7 @@ import UIKit // MARK: - Behavior Execution //-------------------------------------------------- - func executeBehaviors(_ behaviorBlock:(_ behavior:T)->Void) { + func executeBehaviors(_ behaviorBlock: (_ behavior: T) -> Void) { behaviors?.compactMap { $0 as? T }.forEach { behaviorBlock($0) } } } diff --git a/MVMCoreUI/Behaviors/PageBehaviorHandlerModelProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerModelProtocol.swift similarity index 98% rename from MVMCoreUI/Behaviors/PageBehaviorHandlerModelProtocol.swift rename to MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerModelProtocol.swift index 17f1b85e..d9b8da9f 100644 --- a/MVMCoreUI/Behaviors/PageBehaviorHandlerModelProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerModelProtocol.swift @@ -18,8 +18,8 @@ public extension PageBehaviorHandlerModelProtocol { guard !behavior.shouldAllowMultipleInstances, !newBehaviors.contains(where: { $0.behaviorName == behavior.behaviorName }) else { return } + newBehaviors.append(behavior) self.behaviors = newBehaviors } } - diff --git a/MVMCoreUI/Behaviors/PageBehaviorHandlerProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift similarity index 98% rename from MVMCoreUI/Behaviors/PageBehaviorHandlerProtocol.swift rename to MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift index 3b809da0..1d020aeb 100644 --- a/MVMCoreUI/Behaviors/PageBehaviorHandlerProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorHandlerProtocol.swift @@ -6,7 +6,6 @@ // Copyright © 2021 Verizon Wireless. All rights reserved. // -import Foundation public protocol PageBehaviorHandlerProtocol { var behaviors: [PageBehaviorProtocol]? { get set } @@ -19,7 +18,9 @@ public extension PageBehaviorHandlerProtocol { behaviors = nil return } + var behaviors: [PageBehaviorProtocol] = [] + for behaviorModel in behaviorModels { do { let handlerType = try ModelRegistry.getHandler(behaviorModel) as! PageBehaviorProtocol.Type diff --git a/MVMCoreUI/Behaviors/PageBehaviorModelProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorModelProtocol.swift similarity index 92% rename from MVMCoreUI/Behaviors/PageBehaviorModelProtocol.swift rename to MVMCoreUI/Behaviors/Protocols/PageBehaviorModelProtocol.swift index d8502a7e..8b9eabab 100644 --- a/MVMCoreUI/Behaviors/PageBehaviorModelProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorModelProtocol.swift @@ -6,6 +6,7 @@ // Copyright © 2021 Verizon Wireless. All rights reserved. // + public protocol PageBehaviorModelProtocol: ModelProtocol { /// The type of rule @@ -18,11 +19,11 @@ public protocol PageBehaviorModelProtocol: ModelProtocol { public extension PageBehaviorModelProtocol { var behaviorName: String { - get { type(of:self).identifier } + type(of:self).identifier } static var shouldAllowMultipleInstances: Bool { - get { true } + true } static var categoryCodingKey: String { diff --git a/MVMCoreUI/Behaviors/PageBehaviorProtocol.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift similarity index 91% rename from MVMCoreUI/Behaviors/PageBehaviorProtocol.swift rename to MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift index 1eae286f..e7db54bc 100644 --- a/MVMCoreUI/Behaviors/PageBehaviorProtocol.swift +++ b/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocol.swift @@ -6,7 +6,6 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation public protocol PageBehaviorProtocol: ModelHandlerProtocol { @@ -46,9 +45,8 @@ public protocol PageCustomActionHandlerBehavior: PageBehaviorProtocol { } public extension MVMCoreUIDelegateObject { + weak var behaviorTemplateDelegate: (PageBehaviorHandlerProtocol & NSObjectProtocol)? { - get { - return (moleculeDelegate as? PageProtocol)?.pageModel as? (PageBehaviorHandlerProtocol & NSObjectProtocol) - } + (moleculeDelegate as? PageProtocol)?.pageModel as? (PageBehaviorHandlerProtocol & NSObjectProtocol) } } diff --git a/MVMCoreUI/Behaviors/PageBehaviorProtocolRequirer.swift b/MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocolRequirer.swift similarity index 100% rename from MVMCoreUI/Behaviors/PageBehaviorProtocolRequirer.swift rename to MVMCoreUI/Behaviors/Protocols/PageBehaviorProtocolRequirer.swift diff --git a/MVMCoreUI/Containers/Views/Container.swift b/MVMCoreUI/Containers/Views/Container.swift index 159535d7..e3512bab 100644 --- a/MVMCoreUI/Containers/Views/Container.swift +++ b/MVMCoreUI/Containers/Views/Container.swift @@ -18,7 +18,7 @@ open class Container: View, ContainerProtocol { public let containerHelper = ContainerHelper() public var containerModel: ContainerModelProtocol? { - get { return model as? ContainerModelProtocol } + get { model as? ContainerModelProtocol } } //-------------------------------------------------- diff --git a/MVMCoreUI/Containers/Views/ContainerModel.swift b/MVMCoreUI/Containers/Views/ContainerModel.swift index 9e1b3fa8..caa949df 100644 --- a/MVMCoreUI/Containers/Views/ContainerModel.swift +++ b/MVMCoreUI/Containers/Views/ContainerModel.swift @@ -6,7 +6,6 @@ // Copyright © 2019 Verizon Wireless. All rights reserved. // -import Foundation open class ContainerModel: ContainerModelProtocol, Codable { @@ -44,7 +43,7 @@ open class ContainerModel: ContainerModelProtocol, Codable { //-------------------------------------------------- /// Sets the default values. Should be called on init. - open func setDefaults() {} + open func setDefaults() { } //-------------------------------------------------- // MARK: - Initializers diff --git a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift index 5f60a61b..98bec293 100644 --- a/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift +++ b/MVMCoreUI/FormUIHelpers/Rules/Rules/RuleRegexModel.swift @@ -6,8 +6,6 @@ // Copyright © 2020 Verizon Wireless. All rights reserved. // -import Foundation - public class RuleRegexModel: RulesProtocol { //--------------------------------------------------