Merge branch 'develop' into feature/list_onecolumn_fullwidthtext_bodytextonly
* develop: header updates undoing removal mild updates hero is working. commenting done. rolled back change. moved hero is setWithModel. Was not being set. Mild changes. undo commented code Caret fix in table view cell code condensing extra init functions
This commit is contained in:
commit
5dd1c229f9
@ -309,7 +309,7 @@
|
||||
D2A5145F2211DDC100345BFB /* MoleculeStackView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */; };
|
||||
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */; };
|
||||
D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */; };
|
||||
D2A514672213885800345BFB /* HeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A514662213885800345BFB /* HeaderView.swift */; };
|
||||
D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A514662213885800345BFB /* MoleculeHeaderView.swift */; };
|
||||
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; };
|
||||
D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A638FC22CA98280052ED1F /* HeadlineBody.swift */; };
|
||||
D2A6390122CBB1820052ED1F /* Carousel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A6390022CBB1820052ED1F /* Carousel.swift */; };
|
||||
@ -324,6 +324,8 @@
|
||||
D2C521A923EDE79E00CA2634 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2C521A823EDE79E00CA2634 /* ViewController.swift */; };
|
||||
D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */; };
|
||||
D2D6CD4222E78FAB00D701B8 /* ThreeLayerTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */; };
|
||||
D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D90B41240463E100DD6EC9 /* MoleculeHeaderModel.swift */; };
|
||||
D2D90B442404789000DD6EC9 /* MoleculeContainerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D90B432404789000DD6EC9 /* MoleculeContainerProtocol.swift */; };
|
||||
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */; };
|
||||
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */; };
|
||||
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */; };
|
||||
@ -654,7 +656,7 @@
|
||||
D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackView.swift; sourceTree = "<group>"; };
|
||||
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackTemplate.swift; sourceTree = "<group>"; };
|
||||
D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeStackCenteredTemplate.swift; sourceTree = "<group>"; };
|
||||
D2A514662213885800345BFB /* HeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeaderView.swift; sourceTree = "<group>"; };
|
||||
D2A514662213885800345BFB /* MoleculeHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeHeaderView.swift; sourceTree = "<group>"; };
|
||||
D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerViewController.swift; sourceTree = "<group>"; };
|
||||
D2A638FC22CA98280052ED1F /* HeadlineBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBody.swift; sourceTree = "<group>"; };
|
||||
D2A6390022CBB1820052ED1F /* Carousel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Carousel.swift; sourceTree = "<group>"; };
|
||||
@ -669,6 +671,8 @@
|
||||
D2C521A823EDE79E00CA2634 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||
D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scroller.swift; sourceTree = "<group>"; };
|
||||
D2D6CD4122E78FAB00D701B8 /* ThreeLayerTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTemplate.swift; sourceTree = "<group>"; };
|
||||
D2D90B41240463E100DD6EC9 /* MoleculeHeaderModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeHeaderModel.swift; sourceTree = "<group>"; };
|
||||
D2D90B432404789000DD6EC9 /* MoleculeContainerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeContainerProtocol.swift; sourceTree = "<group>"; };
|
||||
D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUIDelegateObject.swift; sourceTree = "<group>"; };
|
||||
D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTableViewController.swift; sourceTree = "<group>"; };
|
||||
D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeListTemplate.swift; sourceTree = "<group>"; };
|
||||
@ -761,6 +765,7 @@
|
||||
children = (
|
||||
9432A79E23DB47BA00719041 /* EntryFieldContainer.swift */,
|
||||
D29E28DE23D740FC00ACEA85 /* Container */,
|
||||
D2D90B432404789000DD6EC9 /* MoleculeContainerProtocol.swift */,
|
||||
014AA72123C501E2006F3E93 /* MoleculeContainerModel.swift */,
|
||||
D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */,
|
||||
);
|
||||
@ -1142,7 +1147,8 @@
|
||||
D224798E2316A995003FCCF9 /* HorizontalCombinationViews */,
|
||||
D224798D2316A988003FCCF9 /* VerticalCombinationViews */,
|
||||
01EB368C23609801006832FA /* HeaderModel.swift */,
|
||||
D2A514662213885800345BFB /* HeaderView.swift */,
|
||||
D2D90B41240463E100DD6EC9 /* MoleculeHeaderModel.swift */,
|
||||
D2A514662213885800345BFB /* MoleculeHeaderView.swift */,
|
||||
012A88EB238F084D00FE3DA1 /* FooterModel.swift */,
|
||||
D274CA322236A78900B01B62 /* FooterView.swift */,
|
||||
0116A4E4228B19640094F3ED /* RadioButtonModel.swift */,
|
||||
@ -1731,7 +1737,7 @@
|
||||
D2E2A99C23D8D975000B42E6 /* ImageHeadlineBodyModel.swift in Sources */,
|
||||
D28A837F23CCA96400DFE4FC /* TabsModel.swift in Sources */,
|
||||
012A88EC238F084D00FE3DA1 /* FooterModel.swift in Sources */,
|
||||
D2A514672213885800345BFB /* HeaderView.swift in Sources */,
|
||||
D2A514672213885800345BFB /* MoleculeHeaderView.swift in Sources */,
|
||||
D29E28D823D21AB800ACEA85 /* StringAndMoleculeView.swift in Sources */,
|
||||
01EB369023609801006832FA /* MoleculeListItemModel.swift in Sources */,
|
||||
D28A838323CCBD3F00DFE4FC /* CircleProgressModel.swift in Sources */,
|
||||
@ -1796,6 +1802,7 @@
|
||||
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */,
|
||||
8D24041523E7FC0B009E23BE /* ListLeftVariableIconWithRightCaretModel.swift in Sources */,
|
||||
D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */,
|
||||
D2D90B42240463E100DD6EC9 /* MoleculeHeaderModel.swift in Sources */,
|
||||
012A88B1238C880100FE3DA1 /* CarouselPagingModelProtocol.swift in Sources */,
|
||||
D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */,
|
||||
9445890E2385C3F800DE9FD4 /* MultiProgressModel.swift in Sources */,
|
||||
@ -1817,6 +1824,7 @@
|
||||
D22D1F47220496A30077CEC0 /* MVMCoreUISwitch.m in Sources */,
|
||||
C695A67F23C9830600BFB94E /* UnOrderedListModel.swift in Sources */,
|
||||
017BEB4223620AD20024EF95 /* FormModelProtocol.swift in Sources */,
|
||||
D2D90B442404789000DD6EC9 /* MoleculeContainerProtocol.swift in Sources */,
|
||||
012A88DB238ED45900FE3DA1 /* CarouselModel.swift in Sources */,
|
||||
D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */,
|
||||
0AE14F64238315D2005417F8 /* TextField.swift in Sources */,
|
||||
|
||||
@ -15,7 +15,7 @@ public class CaretLinkModel: ButtonModelProtocol, MoleculeModelProtocol {
|
||||
public var title: String
|
||||
public var action: ActionModelProtocol
|
||||
public var enabledColor: Color = Color(uiColor: .black)
|
||||
public var disabledColor: Color? = Color(uiColor: .mfSilver())
|
||||
public var disabledColor: Color? = Color(uiColor: .mvmCoolGray6)
|
||||
public var enabled = true
|
||||
|
||||
public init(title: String, action: ActionModelProtocol) {
|
||||
|
||||
@ -58,6 +58,8 @@ import Foundation
|
||||
case isEnabled
|
||||
case action
|
||||
}
|
||||
|
||||
init(isChecked: Bool = false) {}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
|
||||
@ -37,7 +37,10 @@ public class CircleProgressModel: MoleculeModelProtocol {
|
||||
public var colors = [Color]()
|
||||
public var backgroundColor: Color?
|
||||
|
||||
public init() {}
|
||||
public init() {
|
||||
updateStyle()
|
||||
updateSize()
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case style
|
||||
|
||||
@ -231,6 +231,7 @@ public typealias ActionBlock = () -> ()
|
||||
attributedText = nil
|
||||
originalAttributedString = nil
|
||||
text = labelModel.text
|
||||
hero = labelModel.hero
|
||||
Label.setLabel(self, withHTML: labelModel.html)
|
||||
|
||||
let alignment = LabelAlignment(rawValue: labelModel.textAlignment ?? "")
|
||||
@ -344,7 +345,6 @@ public typealias ActionBlock = () -> ()
|
||||
}
|
||||
attributedText = attributedString
|
||||
originalAttributedString = attributedText
|
||||
hero = labelModel.hero
|
||||
}
|
||||
}
|
||||
|
||||
@ -716,6 +716,7 @@ extension Label {
|
||||
public func reset() {
|
||||
text = nil
|
||||
attributedText = nil
|
||||
hero = nil
|
||||
textAlignment = .left
|
||||
originalAttributedString = nil
|
||||
styleB2(true)
|
||||
@ -807,9 +808,6 @@ extension Label {
|
||||
|
||||
- Attention: This method expects text to be set first. Otherwise, it will do nothing.
|
||||
- parameter range: The range of text to be tapped.
|
||||
- parameter actionMap:
|
||||
- parameter delegate:
|
||||
- parameter additionalData:
|
||||
*/
|
||||
@objc public func addTappableLinkAttribute(range: NSRange, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
|
||||
|
||||
@ -10,6 +10,10 @@
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class LabelModel: MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "label"
|
||||
public var backgroundColor: Color?
|
||||
public var text: String
|
||||
@ -24,6 +28,10 @@ import Foundation
|
||||
public var hero: Int?
|
||||
public var makeWholeViewClickable: Bool?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case text
|
||||
@ -43,11 +51,19 @@ import Foundation
|
||||
enum AttributeTypeKey: String, CodingKey {
|
||||
case type
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(text: String) {
|
||||
self.text = text
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
text = try typeContainer.decode(String.self, forKey: .text)
|
||||
|
||||
@ -139,7 +139,6 @@ import UIKit
|
||||
|
||||
topSeparatorView?.updateView(size)
|
||||
bottomSeparatorView?.updateView(size)
|
||||
|
||||
molecule?.updateView(size)
|
||||
}
|
||||
|
||||
@ -153,9 +152,7 @@ import UIKit
|
||||
|
||||
//TODO: Model, Change to model
|
||||
public func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
guard let model = model as? ListItemModelProtocol else {
|
||||
return
|
||||
}
|
||||
guard let model = model as? ListItemModelProtocol else { return }
|
||||
|
||||
self.listItemModel = model
|
||||
style(with: model.style)
|
||||
@ -194,20 +191,21 @@ import UIKit
|
||||
return nil
|
||||
}
|
||||
|
||||
// MARK: - Arrow
|
||||
// MARK: - Caret View
|
||||
/// Adds the standard mvm style caret to the accessory view
|
||||
@objc public func addCaretViewAccessory() {
|
||||
guard accessoryView == nil else { return }
|
||||
caretView = CaretView(lineWidth: 1)
|
||||
caretView?.translatesAutoresizingMaskIntoConstraints = true
|
||||
caretView?.size = .small(.vertical)
|
||||
caretView?.setConstraints()
|
||||
|
||||
if let size = caretView?.size?.dimensions() {
|
||||
let caret = CaretView(lineWidth: 1)
|
||||
caret.translatesAutoresizingMaskIntoConstraints = true
|
||||
caret.size = .small(.vertical)
|
||||
if let size = caret.size?.dimensions() {
|
||||
caret.frame = CGRect(origin: CGPoint.zero, size: size)
|
||||
caretViewWidthSizeObject = MFSizeObject(standardSize: size.width, standardiPadPortraitSize: 9)
|
||||
caretViewHeightSizeObject = MFSizeObject(standardSize: size.height, standardiPadPortraitSize: 16)
|
||||
}
|
||||
accessoryView = caretView
|
||||
caretView = caret
|
||||
accessoryView = caret
|
||||
}
|
||||
|
||||
/// NOTE: Should only be called when displayed or about to be displayed.
|
||||
@ -217,11 +215,11 @@ import UIKit
|
||||
layoutIfNeeded()
|
||||
guard let heroLabel = findHeroLabel(views: contentView.subviews), let hero = heroLabel.hero else { return }
|
||||
let rect = Label.boundingRect(forCharacterRange: NSRange(location: hero, length: 1), in: heroLabel)
|
||||
accessoryView?.center.y = contentView.convert(UIView(frame: rect).center, from: heroLabel).y
|
||||
accessoryView?.center.y = convert(UIView(frame: rect).center, from: heroLabel).y
|
||||
heroAccessoryCenter = accessoryView?.center
|
||||
}
|
||||
|
||||
/// Traverses the view hierarchy for a 🦸♂️heroic Label.
|
||||
/// Traverses the view hierarchy for a 🦸♂️ heroic Label.
|
||||
private func findHeroLabel(views: [UIView]) -> Label? {
|
||||
|
||||
if views.isEmpty {
|
||||
|
||||
@ -27,6 +27,12 @@ public class ContainerModel: ContainerModelProtocol, Codable {
|
||||
}
|
||||
|
||||
public init() {}
|
||||
|
||||
public convenience init(horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil) {
|
||||
self.init()
|
||||
self.horizontalAlignment = horizontalAlignment
|
||||
self.verticalAlignment = verticalAlignment
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
|
||||
@ -31,7 +31,7 @@ open class MoleculeContainer: Container {
|
||||
}
|
||||
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
if let casteModel = model as? MoleculeContainerModel {
|
||||
if let casteModel = model as? MoleculeContainerModelProtocol {
|
||||
if view != nil {
|
||||
(view as? ModelMoleculeViewProtocol)?.setWithModel(casteModel.molecule, delegateObject, additionalData)
|
||||
} else {
|
||||
@ -44,7 +44,7 @@ open class MoleculeContainer: Container {
|
||||
}
|
||||
|
||||
public override static func nameForReuse(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||
guard let containerModel = model as? MoleculeContainerModel,
|
||||
guard let containerModel = model as? MoleculeContainerModelProtocol,
|
||||
let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(containerModel.molecule) as? ModelMoleculeViewProtocol.Type,
|
||||
let moleculeName = moleculeClass.nameForReuse(containerModel.molecule, delegateObject) else {
|
||||
return "\(model?.moleculeName ?? "moleculeContainer")<>"
|
||||
@ -53,7 +53,7 @@ open class MoleculeContainer: Container {
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
guard let containerModel = molecule as? MoleculeContainerModel else { return 0 }
|
||||
guard let containerModel = molecule as? MoleculeContainerModelProtocol else { return 0 }
|
||||
guard let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(containerModel.molecule) as? ModelMoleculeViewProtocol.Type,
|
||||
let moleculeHeight = moleculeClass.estimatedHeight(forRow: containerModel.molecule, delegateObject: delegateObject) else {
|
||||
return (containerModel.topMarginPadding ?? 0) + (containerModel.bottomMarginPadding ?? 0)
|
||||
@ -62,7 +62,7 @@ open class MoleculeContainer: Container {
|
||||
}
|
||||
|
||||
public override class func requiredModules(_ molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
||||
guard let containerModel = molecule as? MoleculeContainerModel,
|
||||
guard let containerModel = molecule as? MoleculeContainerModelProtocol,
|
||||
let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(containerModel.molecule) as? ModelMoleculeViewProtocol.Type else { return nil }
|
||||
return moleculeClass.requiredModules(containerModel.molecule, delegateObject: delegateObject, error: error)
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public class MoleculeContainerModel: ContainerModel {
|
||||
public class MoleculeContainerModel: ContainerModel, MoleculeContainerModelProtocol {
|
||||
public var molecule: MoleculeModelProtocol
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
|
||||
13
MVMCoreUI/Containers/Views/MoleculeContainerProtocol.swift
Normal file
13
MVMCoreUI/Containers/Views/MoleculeContainerProtocol.swift
Normal file
@ -0,0 +1,13 @@
|
||||
//
|
||||
// MoleculeContainerProtocol.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 2/24/20.
|
||||
// Copyright © 2020 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
public protocol MoleculeContainerModelProtocol: ContainerModelProtocol {
|
||||
var molecule: MoleculeModelProtocol { get set }
|
||||
}
|
||||
@ -8,49 +8,33 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class ListLeftVariableCheckboxAllTextAndLinks: TableViewCell {
|
||||
@objcMembers open class ListLeftVariableCheckboxAllTextAndLinks: TableViewCell {
|
||||
public let checkbox = Checkbox(frame: .zero)
|
||||
public let eyebrowHeadlineBodyLink = EyebrowHeadlineBodyLink(frame: .zero)
|
||||
public let stack = Stack<StackModel>(frame: .zero)
|
||||
|
||||
// MARK: - View Lifecycle
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
stack.updateView(size)
|
||||
}
|
||||
|
||||
override open func setupView() {
|
||||
super.setupView()
|
||||
stack.stackItems = [StackItem(andContain: checkbox),StackItem(andContain: eyebrowHeadlineBodyLink)]
|
||||
contentView.addSubview(stack)
|
||||
containerHelper.constrainView(stack)
|
||||
}
|
||||
|
||||
// MARK:- ModelMoleculeViewProtocol
|
||||
override open func reset() {
|
||||
super.reset()
|
||||
stack.reset()
|
||||
addMolecule(stack)
|
||||
}
|
||||
|
||||
// MARK:- MVMCoreUIMoleculeViewProtocol
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
guard let model = model as? ListLeftVariableCheckboxAllTextAndLinksModel else { return}
|
||||
checkbox.setWithModel(model.checkbox, delegateObject, additionalData)
|
||||
eyebrowHeadlineBodyLink.setWithModel(model.eyebrowHeadlineBodyLink, delegateObject, additionalData)
|
||||
|
||||
// Create a stack model to use for the internal stack and set the alignment of labels
|
||||
let checkbox = StackItemModel()
|
||||
checkbox.horizontalAlignment = .fill
|
||||
let eyebrowHeadlineBodyLink = StackItemModel()
|
||||
eyebrowHeadlineBodyLink.horizontalAlignment = .leading
|
||||
let stackModel = StackModel(molecules: [checkbox,eyebrowHeadlineBodyLink])
|
||||
stackModel.axis = .horizontal
|
||||
let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .fill),
|
||||
StackItemModel(horizontalAlignment: .leading)],
|
||||
axis: .horizontal)
|
||||
stack.model = stackModel
|
||||
stack.restack()
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 140
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ public class ListLeftVariableCheckboxAllTextAndLinksModel: ListItemModel, Molecu
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
eyebrowHeadlineBodyLink = try typeContainer.decode(EyebrowHeadlineBodyLinkModel.self, forKey: .eyebrowHeadlineBodyLink)
|
||||
checkbox = try typeContainer.decode(CheckboxModel.self, forKey: .checkbox)
|
||||
checkbox = try typeContainer.decodeIfPresent(CheckboxModel.self, forKey: .checkbox) ?? CheckboxModel()
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
import Foundation
|
||||
import UIKit
|
||||
|
||||
@objcMembers public class ListLeftVariableIconWithRightCaret: TableViewCell {
|
||||
@objcMembers open class ListLeftVariableIconWithRightCaret: TableViewCell {
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
@ -22,17 +22,11 @@ import UIKit
|
||||
//-----------------------------------------------------
|
||||
// MARK: - View Lifecycle
|
||||
//-------------------------------------------------------
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
stack.updateView(size)
|
||||
}
|
||||
|
||||
override open func setupView() {
|
||||
super.setupView()
|
||||
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||
stack.stackItems = [StackItem(andContain: leftImage),StackItem(andContain: leftLabel),StackItem(andContain: rightLabel)]
|
||||
contentView.addSubview(stack)
|
||||
containerHelper.constrainView(stack)
|
||||
addMolecule(stack)
|
||||
leftLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 901), for: .horizontal)
|
||||
rightLabel.setContentHuggingPriority(UILayoutPriority(rawValue: 902), for: .horizontal)
|
||||
}
|
||||
@ -40,32 +34,28 @@ import UIKit
|
||||
//----------------------------------------------------
|
||||
// MARK: - Molecule
|
||||
//------------------------------------------------------
|
||||
override open func reset() {
|
||||
super.reset()
|
||||
stack.reset()
|
||||
}
|
||||
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
guard let model = model as? ListLeftVariableIconWithRightCaretModel else { return}
|
||||
leftImage.setWithModel(model.image, delegateObject, additionalData)
|
||||
leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData)
|
||||
rightLabel.setWithModel(model.rightLabel, delegateObject, additionalData)
|
||||
|
||||
// Create a stack model to use for the internal stack and set the alignment of labels
|
||||
let leftImage = StackItemModel()
|
||||
leftImage.horizontalAlignment = .fill
|
||||
let leftLabel = StackItemModel()
|
||||
leftLabel.horizontalAlignment = .fill
|
||||
let rightLabel = StackItemModel()
|
||||
rightLabel.horizontalAlignment = .trailing
|
||||
let stackModel = StackModel(molecules: [leftImage,leftLabel,rightLabel])
|
||||
stackModel.axis = .horizontal
|
||||
let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .fill),
|
||||
StackItemModel(horizontalAlignment: .fill),
|
||||
StackItemModel(horizontalAlignment: .trailing)],
|
||||
axis: .horizontal)
|
||||
stack.model = stackModel
|
||||
stack.restack()
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 90
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
leftLabel.styleB2(true)
|
||||
rightLabel.styleB2(true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -19,6 +19,7 @@ public class ListLeftVariableIconWithRightCaretModel: ListItemModel, MoleculeMod
|
||||
if image.height == nil {
|
||||
image.height = 30.0
|
||||
}
|
||||
rightLabel.hero = 0
|
||||
}
|
||||
|
||||
public init(image: ImageViewModel, leftLabel: LabelModel, rightLabel: LabelModel) {
|
||||
@ -43,7 +44,7 @@ public class ListLeftVariableIconWithRightCaretModel: ListItemModel, MoleculeMod
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
|
||||
@ -13,46 +13,30 @@ import Foundation
|
||||
let rightLabel = Label.commonLabelB2(true)
|
||||
let stack = Stack<StackModel>(frame: .zero)
|
||||
|
||||
//-------------------------------------------------
|
||||
// MARK: - View Cycle
|
||||
//-------------------------------------------------
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
stack.updateView(size)
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// MARK: - Setup
|
||||
//-------------------------------------------------
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
rightLabel.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 900), for: .horizontal)
|
||||
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||
stack.stackItems = [StackItem(andContain: leftLabel),StackItem(andContain: wheel),StackItem(andContain: rightLabel)]
|
||||
contentView.addSubview(stack)
|
||||
containerHelper.constrainView(stack)
|
||||
addMolecule(stack)
|
||||
}
|
||||
|
||||
//-------------------------------------------------
|
||||
// MARK: - ModelMoleculeViewProtocol
|
||||
//-------------------------------------------------
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
guard let model = model as? ListRVWheelModel else { return }
|
||||
leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData)
|
||||
rightLabel.setWithModel(model.rightLabel, delegateObject, additionalData)
|
||||
wheel.setWithModel(model.wheel, delegateObject, additionalData)
|
||||
|
||||
// Create a stack model to use for the internal stack and set the alignment of models
|
||||
let leftLabelStackItem = StackItemModel()
|
||||
leftLabelStackItem.horizontalAlignment = .leading
|
||||
let wheelStackItem = StackItemModel()
|
||||
wheelStackItem.horizontalAlignment = .fill
|
||||
let rightLabelStackItem = StackItemModel()
|
||||
rightLabelStackItem.horizontalAlignment = .fill
|
||||
rightLabelStackItem.spacing = 4
|
||||
let stackModel = StackModel(molecules: [leftLabelStackItem,wheelStackItem,rightLabelStackItem])
|
||||
stackModel.axis = .horizontal
|
||||
let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .leading),
|
||||
StackItemModel(horizontalAlignment: .fill),
|
||||
StackItemModel(spacing: 4, horizontalAlignment: .fill)],
|
||||
axis: .horizontal)
|
||||
stack.model = stackModel
|
||||
stack.restack()
|
||||
}
|
||||
@ -62,7 +46,6 @@ import Foundation
|
||||
//-------------------------------------------------
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
stack.reset()
|
||||
leftLabel.styleB1(true)
|
||||
rightLabel.styleB2(true)
|
||||
}
|
||||
|
||||
@ -20,6 +20,12 @@ public class ListRVWheelModel: ListItemModel, MoleculeModelProtocol {
|
||||
super.init()
|
||||
}
|
||||
|
||||
/// Defaults to set
|
||||
override public func setDefaults() {
|
||||
super.setDefaults()
|
||||
rightLabel.hero = 0
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case leftLabel
|
||||
@ -31,7 +37,7 @@ public class ListRVWheelModel: ListItemModel, MoleculeModelProtocol {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
leftLabel = try typeContainer.decode(LabelModel.self, forKey: .leftLabel)
|
||||
rightLabel = try typeContainer.decode(LabelModel.self, forKey: .rightLabel)
|
||||
wheel = try typeContainer.decode(CircleProgressModel.self, forKey: .wheel)
|
||||
wheel = try typeContainer.decodeIfPresent(CircleProgressModel.self, forKey: .wheel) ?? CircleProgressModel()
|
||||
try super.init(from: decoder)
|
||||
}
|
||||
|
||||
|
||||
@ -8,12 +8,11 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class ListRightVariablePayments: TableViewCell {
|
||||
@objcMembers open class ListRightVariablePayments: TableViewCell {
|
||||
|
||||
//-----------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//-------------------------------------------------------
|
||||
|
||||
let leftLabel = Label.commonLabelB1(true)
|
||||
let rightImage = MFLoadImageView(pinnedEdges: .all)
|
||||
let stack = Stack<StackModel>(frame: .zero)
|
||||
@ -21,49 +20,34 @@ import Foundation
|
||||
//-----------------------------------------------------
|
||||
// MARK: - View Lifecycle
|
||||
//-------------------------------------------------------
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
stack.updateView(size)
|
||||
}
|
||||
|
||||
override open func setupView() {
|
||||
super.setupView()
|
||||
guard leftLabel.superview == nil else {
|
||||
return
|
||||
}
|
||||
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||
stack.stackItems = [StackItem(andContain: leftLabel),StackItem(andContain: rightImage)]
|
||||
contentView.addSubview(stack)
|
||||
containerHelper.constrainView(stack)
|
||||
addMolecule(stack)
|
||||
}
|
||||
|
||||
//----------------------------------------------------
|
||||
// MARK: - Molecule
|
||||
//------------------------------------------------------
|
||||
override open func reset() {
|
||||
super.reset()
|
||||
stack.reset()
|
||||
}
|
||||
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
guard let model = model as? ListRightVariablePaymentsModel else { return }
|
||||
leftLabel.setWithModel(model.leftLabel, delegateObject, additionalData)
|
||||
rightImage.setWithModel(model.image, delegateObject, additionalData)
|
||||
|
||||
// Create a stack model to use for the internal stack and set the alignment of label and image
|
||||
let leftLabel = StackItemModel()
|
||||
leftLabel.horizontalAlignment = .leading
|
||||
let rightImage = StackItemModel()
|
||||
rightImage.horizontalAlignment = .fill
|
||||
let stackModel = StackModel(molecules: [leftLabel,rightImage])
|
||||
stackModel.axis = .horizontal
|
||||
let stackModel = StackModel(molecules: [StackItemModel(horizontalAlignment: .leading),
|
||||
StackItemModel(horizontalAlignment: .fill)],
|
||||
axis: .horizontal)
|
||||
stack.model = stackModel
|
||||
stack.restack()
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat? {
|
||||
return 65
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
leftLabel.styleB1(true)
|
||||
}
|
||||
}
|
||||
|
||||
@ -20,6 +20,12 @@ public class ListRightVariablePaymentsModel: ListItemModel, MoleculeModelProtoco
|
||||
super.init()
|
||||
}
|
||||
|
||||
/// Defaults to set
|
||||
override public func setDefaults() {
|
||||
super.setDefaults()
|
||||
leftLabel.hero = 0
|
||||
}
|
||||
|
||||
static func createPayPalImage() -> ImageViewModel {
|
||||
let image = ImageViewModel(image: "imageName_PayPal_logo")
|
||||
image.localBundle = MVMCoreUIUtility.bundleForMVMCoreUI()
|
||||
|
||||
@ -16,23 +16,16 @@ import Foundation
|
||||
let stack = Stack<StackModel>(frame: .zero)
|
||||
|
||||
// MARK: - MFViewProtocol
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
stack.updateView(size)
|
||||
}
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
|
||||
//using stackItems to align the three headlineBody
|
||||
stack.translatesAutoresizingMaskIntoConstraints = false
|
||||
stack.stackItems = [StackItem(andContain: leftHeadlineBody),StackItem(andContain: centerHeadLineBody),StackItem(andContain: rightHeadLineBody)]
|
||||
contentView.addSubview(stack)
|
||||
containerHelper.constrainView(stack)
|
||||
addMolecule(stack)
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
guard let model = model as? ListThreeColumnPlanDataDividerModel else { return }
|
||||
leftHeadlineBody.setWithModel(model.leftHeadlineBody, delegateObject, additionalData)
|
||||
@ -40,24 +33,15 @@ import Foundation
|
||||
rightHeadLineBody.setWithModel(model.rightHeadlineBody, delegateObject, additionalData)
|
||||
|
||||
// Create a stack model to use for the internal stack and set the alignment of models
|
||||
let leftHeadlineBodyAlignment = StackItemModel(percent: 33)
|
||||
leftHeadlineBodyAlignment.horizontalAlignment = .leading
|
||||
let centerHeadLineBodyAlignment = StackItemModel(percent: 34)
|
||||
centerHeadLineBodyAlignment.horizontalAlignment = .center
|
||||
let rightHeadLineBodyAlignment = StackItemModel(percent: 33)
|
||||
rightHeadLineBodyAlignment.horizontalAlignment = .trailing
|
||||
let stackModel = StackModel(molecules: [leftHeadlineBodyAlignment,centerHeadLineBodyAlignment,rightHeadLineBodyAlignment])
|
||||
stackModel.axis = .horizontal
|
||||
let stackModel = StackModel(molecules: [StackItemModel(percent: 33, horizontalAlignment: .leading),
|
||||
StackItemModel(percent: 34, horizontalAlignment: .center),
|
||||
StackItemModel(percent: 33, horizontalAlignment: .trailing)],
|
||||
axis: .horizontal)
|
||||
stack.model = stackModel
|
||||
stack.restack()
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
stack.reset()
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
open override class func estimatedHeight(forRow molecule: MoleculeModelProtocol?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
return 121
|
||||
}
|
||||
}
|
||||
|
||||
@ -26,6 +26,9 @@ public class ListThreeColumnPlanDataDividerModel: ListItemModel, MoleculeModelPr
|
||||
override public func setDefaults() {
|
||||
super.setDefaults()
|
||||
style = "tallDivider"
|
||||
leftHeadlineBody.style = "itemHeader"
|
||||
centerHeadlineBody.style = "itemHeader"
|
||||
rightHeadlineBody.style = "itemHeader"
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
|
||||
@ -8,19 +8,17 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class HeaderModel: MoleculeContainerModel, MoleculeModelProtocol {
|
||||
public static var identifier: String = "header"
|
||||
@objcMembers public class HeaderModel: ContainerModel {
|
||||
public var backgroundColor: Color?
|
||||
public var line: LineModel?
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case line
|
||||
case backgroundColor
|
||||
}
|
||||
|
||||
/// Defaults to set
|
||||
func setDefaults() {
|
||||
public func setDefaults() {
|
||||
if useHorizontalMargins == nil {
|
||||
useHorizontalMargins = true
|
||||
}
|
||||
@ -33,25 +31,27 @@ import Foundation
|
||||
if bottomMarginPadding == nil {
|
||||
bottomMarginPadding = PaddingDefaultVerticalSpacing
|
||||
}
|
||||
line?.type = .heavy
|
||||
if line == nil {
|
||||
line = LineModel(type: .heavy)
|
||||
}
|
||||
}
|
||||
|
||||
public override init(with moleculeModel: MoleculeModelProtocol) {
|
||||
super.init(with: moleculeModel)
|
||||
public override init() {
|
||||
super.init()
|
||||
setDefaults()
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
try super.init(from: decoder)
|
||||
setDefaults()
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line) ?? LineModel(type: .heavy)
|
||||
line = try typeContainer.decodeIfPresent(LineModel.self, forKey: .line)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
setDefaults()
|
||||
}
|
||||
|
||||
public override func encode(to encoder: Encoder) throws {
|
||||
try super.encode(to: encoder)
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encode(line, forKey: .line)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
}
|
||||
|
||||
@ -16,13 +16,14 @@ import Foundation
|
||||
public var percent: Int?
|
||||
public var gone: Bool = false
|
||||
|
||||
public convenience init(gone: Bool) {
|
||||
self.init()
|
||||
self.gone = gone
|
||||
}
|
||||
|
||||
public convenience init(percent: Int) {
|
||||
public convenience init(spacing: CGFloat? = nil, percent: Int? = nil, horizontalAlignment: UIStackView.Alignment? = nil, verticalAlignment: UIStackView.Alignment? = nil, gone: Bool? = nil) {
|
||||
self.init()
|
||||
self.horizontalAlignment = horizontalAlignment
|
||||
self.verticalAlignment = verticalAlignment
|
||||
self.spacing = spacing
|
||||
self.percent = percent
|
||||
if let gone = gone {
|
||||
self.gone = gone
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
37
MVMCoreUI/Molecules/MoleculeHeaderModel.swift
Normal file
37
MVMCoreUI/Molecules/MoleculeHeaderModel.swift
Normal file
@ -0,0 +1,37 @@
|
||||
//
|
||||
// MoleculeHeaderModel.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Suresh, Kamlesh on 10/3/19.
|
||||
// Copyright © 2019 Suresh, Kamlesh. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
|
||||
@objcMembers public class MoleculeHeaderModel: HeaderModel, MoleculeModelProtocol, MoleculeContainerModelProtocol {
|
||||
public static var identifier: String = "header"
|
||||
public var molecule: MoleculeModelProtocol
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case molecule
|
||||
}
|
||||
|
||||
public init(with moleculeModel: MoleculeModelProtocol) {
|
||||
molecule = moleculeModel
|
||||
super.init()
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
molecule = try typeContainer.decodeMolecule(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)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeModel(molecule, forKey: .molecule)
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,5 @@
|
||||
//
|
||||
// HeaderView.swift
|
||||
// MoleculeHeaderView.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 2/12/19.
|
||||
@ -8,55 +8,41 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
public class HeaderView: MoleculeContainer {
|
||||
var line: Line?
|
||||
public class MoleculeHeaderView: MoleculeContainer {
|
||||
var line = Line()
|
||||
|
||||
var headerModel: HeaderModel? {
|
||||
get { return model as? HeaderModel }
|
||||
var headerModel: MoleculeHeaderModel? {
|
||||
get { return model as? MoleculeHeaderModel }
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
line?.updateView(size)
|
||||
line.updateView(size)
|
||||
}
|
||||
|
||||
public override func setupView() {
|
||||
super.setupView()
|
||||
|
||||
guard line == nil else { return }
|
||||
let line = Line()
|
||||
line.setStyle(.heavy)
|
||||
addSubview(line)
|
||||
NSLayoutConstraint.pinViewBottom(toSuperview: line, useMargins: false, constant: 0).isActive = true
|
||||
NSLayoutConstraint.pinViewLeft(toSuperview: line, useMargins: true, constant: 0).isActive = true
|
||||
NSLayoutConstraint.pinViewRight(toSuperview: line, useMargins: true, constant: 0).isActive = true
|
||||
self.line = line
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
if let separatorJSON = json?.optionalDictionaryForKey("line") {
|
||||
line?.setWithJSON(separatorJSON, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
|
||||
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
|
||||
guard let headerModel = model as? HeaderModel else {
|
||||
return
|
||||
}
|
||||
|
||||
if let seperatorModel = headerModel.line {
|
||||
line?.setWithJSON(seperatorModel.toJSON(), delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
line?.setStyle(.heavy)
|
||||
line.setStyle(.heavy)
|
||||
}
|
||||
|
||||
// MARK: - ModelMoleculeViewProtocol
|
||||
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
guard let headerModel = headerModel else { return }
|
||||
if let lineModel = headerModel.line {
|
||||
line.setWithModel(lineModel, delegateObject, additionalData)
|
||||
}
|
||||
}
|
||||
|
||||
public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
@ -9,19 +9,30 @@
|
||||
import UIKit
|
||||
|
||||
@objcMembers open class EyebrowHeadlineBodyLink: Container {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
|
||||
let stack = Stack<StackModel>(frame: .zero)
|
||||
let eyebrow = Label.commonLabelB3(true)
|
||||
let headline = Label.commonLabelB1(true)
|
||||
let body = Label.commonLabelB2(true)
|
||||
let link = Link()
|
||||
|
||||
var casteModel: EyebrowHeadlineBodyLinkModel? {
|
||||
get { return model as? EyebrowHeadlineBodyLinkModel }
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MFViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
stack.stackItems = [StackItem(andContain: eyebrow),StackItem(andContain: headline),StackItem(andContain: body),StackItem(andContain: link)]
|
||||
stack.stackItems = [StackItem(andContain: eyebrow),
|
||||
StackItem(andContain: headline),
|
||||
StackItem(andContain: body),
|
||||
StackItem(andContain: link)]
|
||||
addSubview(stack)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: stack)
|
||||
}
|
||||
@ -31,7 +42,10 @@ import UIKit
|
||||
stack.updateView(size)
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
stack.reset()
|
||||
@ -41,16 +55,23 @@ import UIKit
|
||||
body.styleB2(true)
|
||||
}
|
||||
|
||||
// MARK:- ModelMoleculeViewProtocol
|
||||
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
//--------------------------------------------------
|
||||
// MARK: - ModelMoleculeViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
open override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
|
||||
eyebrow.setWithModel(casteModel?.eyebrow, delegateObject, additionalData)
|
||||
headline.setWithModel(casteModel?.headline, delegateObject, additionalData)
|
||||
body.setWithModel(casteModel?.body, delegateObject, additionalData)
|
||||
link.setWithModel(casteModel?.link, delegateObject, additionalData)
|
||||
|
||||
// Create a stack model to use for the internal stack.
|
||||
let stackModel = StackModel(molecules: [StackItemModel(gone: !eyebrow.hasText),StackItemModel(gone: !headline.hasText),StackItemModel(gone: !body.hasText),StackItemModel(gone: (link.titleLabel?.text?.count ?? 0) == 0)])
|
||||
let stackModel = StackModel(molecules: [StackItemModel(gone: !eyebrow.hasText),
|
||||
StackItemModel(gone: !headline.hasText),
|
||||
StackItemModel(gone: !body.hasText),
|
||||
StackItemModel(gone: (link.titleLabel?.text?.count ?? 0) == 0)])
|
||||
stackModel.spacing = 0
|
||||
stack.model = stackModel
|
||||
stack.restack()
|
||||
|
||||
@ -8,7 +8,11 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
public struct EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol {
|
||||
public class EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public static var identifier: String = "eyebrowHeadlineBodyLink"
|
||||
public var moleculeName: String? = EyebrowHeadlineBodyLinkModel.identifier
|
||||
public var backgroundColor: Color?
|
||||
@ -16,4 +20,72 @@ public struct EyebrowHeadlineBodyLinkModel: MoleculeModelProtocol {
|
||||
public var headline: LabelModel?
|
||||
public var body: LabelModel?
|
||||
public var link: LinkModel?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializer
|
||||
//--------------------------------------------------
|
||||
|
||||
public init(eyebrow: LabelModel? = nil, headline: LabelModel? = nil, body: LabelModel? = nil, link: LinkModel? = nil) throws {
|
||||
// TODO: This class initializers should ensure that atleast one item is set.
|
||||
/*guard eyebrow != nil || headline != nil || body != nil || link != nil else {
|
||||
throw
|
||||
}*/
|
||||
self.eyebrow = eyebrow
|
||||
self.headline = headline
|
||||
self.body = body
|
||||
self.link = link
|
||||
setDefaults()
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Method
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Defaults to set
|
||||
public func setDefaults() {
|
||||
if let headline = headline {
|
||||
headline.hero = 0
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Keys
|
||||
//--------------------------------------------------
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case backgroundColor
|
||||
case eyebrow
|
||||
case headline
|
||||
case body
|
||||
case link
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Codec
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
let typeContainer = try decoder.container(keyedBy: CodingKeys.self)
|
||||
backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor)
|
||||
eyebrow = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .eyebrow)
|
||||
headline = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .headline)
|
||||
body = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .body)
|
||||
link = try typeContainer.decodeIfPresent(LinkModel.self, forKey: .link)
|
||||
setDefaults()
|
||||
// TODO: This class initializers should ensure that atleast one item is set.
|
||||
/*guard eyebrow != nil || headline != nil || body != nil || link != nil else {
|
||||
throw
|
||||
}*/
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.container(keyedBy: CodingKeys.self)
|
||||
try container.encode(moleculeName, forKey: .moleculeName)
|
||||
try container.encodeIfPresent(backgroundColor, forKey: .backgroundColor)
|
||||
try container.encodeIfPresent(eyebrow, forKey: .eyebrow)
|
||||
try container.encodeIfPresent(headline, forKey: .headline)
|
||||
try container.encodeIfPresent(body, forKey: .body)
|
||||
try container.encodeIfPresent(link, forKey: .link)
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,15 +8,24 @@
|
||||
|
||||
import Foundation
|
||||
|
||||
|
||||
open class Stack<T>: Container where T: StackModelProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
var contentView: UIView = MVMCoreUICommonViewsUtility.commonView()
|
||||
var stackModel: T? {
|
||||
get { return model as? T }
|
||||
}
|
||||
var stackItems: [UIView] = []
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Helpers
|
||||
//--------------------------------------------------
|
||||
|
||||
public func pinView(_ view: UIView, toView: UIView, attribute: NSLayoutConstraint.Attribute, relation: NSLayoutConstraint.Relation, priority: UILayoutPriority, constant: CGFloat) {
|
||||
|
||||
let constraint = NSLayoutConstraint(item: view, attribute: attribute, relatedBy: relation, toItem: toView, attribute: attribute, multiplier: 1.0, constant: constant)
|
||||
constraint.priority = priority
|
||||
constraint.isActive = true
|
||||
@ -45,13 +54,16 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
||||
item.removeFromSuperview()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
// MARK: - Inits
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
|
||||
public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
super.init(frame: CGRect.zero)
|
||||
setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
@ -60,12 +72,13 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MFViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
public override func setupView() {
|
||||
super.setupView()
|
||||
guard contentView.superview == nil else {
|
||||
return
|
||||
}
|
||||
guard contentView.superview == nil else { return }
|
||||
MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0)
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
backgroundColor = .clear
|
||||
@ -82,7 +95,10 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
//--------------------------------------------------
|
||||
|
||||
public override func reset() {
|
||||
super.reset()
|
||||
backgroundColor = .clear
|
||||
@ -91,7 +107,7 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
public override func setWithModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
let previousModel = self.model
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
removeAllItemViews()
|
||||
@ -132,6 +148,7 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
||||
guard let model = molecule as? T else { return 0 }
|
||||
let horizontal = model.axis == .horizontal
|
||||
var estimatedHeight: CGFloat = 0
|
||||
|
||||
for case let item in model.molecules {
|
||||
if item.gone { continue }
|
||||
let height = (MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(item) as? ModelMoleculeViewProtocol.Type)?.estimatedHeight(forRow: item, delegateObject: delegateObject) ?? 0
|
||||
@ -158,26 +175,31 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
||||
return modules.count > 0 ? modules : nil
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Subclassables
|
||||
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Can be subclassed to create views when we get stack item models and have no views yet
|
||||
func createStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
}
|
||||
func createStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) { }
|
||||
|
||||
/// Can be subclassed to set stack items with model when we already have views
|
||||
func setStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable : Any]?) {
|
||||
func setStackItemsFromModel(_ model: MoleculeModelProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [AnyHashable: Any]?) {
|
||||
guard let models = stackModel?.molecules else { return }
|
||||
for (index, element) in models.enumerated() {
|
||||
(stackItems[index] as? ModelMoleculeViewProtocol)?.setWithModel(element, delegateObject, additionalData)
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Adding to stack
|
||||
//--------------------------------------------------
|
||||
|
||||
/// Gets the percent modifier. This value is used to help properly calculate percent for stack items when spacing is involved.
|
||||
private func getTotalSpace() -> CGFloat {
|
||||
guard let stackModel = stackModel else { return 0.0 }
|
||||
var totalSpace: CGFloat = 0.0
|
||||
var firstMoleculeFound = false
|
||||
|
||||
for stackItemModel in stackModel.molecules {
|
||||
guard !stackItemModel.gone else { continue }
|
||||
let spacing = stackItemModel.spacing ?? stackModel.spacing
|
||||
@ -222,7 +244,7 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
||||
pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0)
|
||||
pinView(contentView, toView: view, attribute: .trailing, relation: .equal, priority: .required, constant: 0)
|
||||
if let percent = model.percent {
|
||||
let multiplier = CGFloat(percent)/100.0
|
||||
let multiplier = CGFloat(percent) / 100.0
|
||||
let constant = multiplier * totalSpacing
|
||||
view.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: multiplier, constant: -constant).isActive = true
|
||||
}
|
||||
@ -241,7 +263,7 @@ open class Stack<T>: Container where T: StackModelProtocol {
|
||||
pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 0)
|
||||
pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0)
|
||||
if let percent = model.percent {
|
||||
let multiplier = CGFloat(percent)/100.0
|
||||
let multiplier = CGFloat(percent) / 100.0
|
||||
let constant = multiplier * totalSpacing
|
||||
view.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: multiplier, constant: -constant).isActive = true
|
||||
}
|
||||
|
||||
@ -16,8 +16,9 @@ import Foundation
|
||||
public var spacing: CGFloat = 16.0
|
||||
public var useStackSpacingBeforeFirstItem = false
|
||||
|
||||
public init(molecules: [StackItemModel]) {
|
||||
public init(molecules: [StackItemModel], axis: NSLayoutConstraint.Axis = .vertical) {
|
||||
self.molecules = molecules
|
||||
self.axis = axis
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
|
||||
@ -90,7 +90,7 @@ import Foundation
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeCollectionViewCell.self, viewModelClass: CarouselItemModel.self)
|
||||
|
||||
// Other Container Molecules
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: HeaderView.self, viewModelClass: HeaderModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: MoleculeHeaderView.self, viewModelClass: MoleculeHeaderModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: FooterView.self, viewModelClass: FooterModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: Scroller.self, viewModelClass: ScrollerModel.self)
|
||||
MVMCoreUIMoleculeMappingObject.shared()?.register(viewClass: ModuleMolecule.self, viewModelClass: ModuleMoleculeModel.self)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user