merge fixes
This commit is contained in:
commit
d5cf307de4
@ -100,6 +100,7 @@
|
||||
D22D1F47220496A30077CEC0 /* MVMCoreUISwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */; };
|
||||
D22D1F562204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = D22D1F542204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F552204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m */; };
|
||||
D243859923A16B1800332775 /* Container.swift in Sources */ = {isa = PBXBuildFile; fileRef = D243859823A16B1800332775 /* Container.swift */; };
|
||||
D260D7B122D65BDD007E7233 /* MVMCoreUIPageControl.h in Headers */ = {isa = PBXBuildFile; fileRef = D260D7AF22D65BDD007E7233 /* MVMCoreUIPageControl.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D260D7B222D65BDD007E7233 /* MVMCoreUIPageControl.m in Sources */ = {isa = PBXBuildFile; fileRef = D260D7B022D65BDD007E7233 /* MVMCoreUIPageControl.m */; };
|
||||
D260D7B622D68514007E7233 /* MVMCoreUIPagingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@ -251,6 +252,8 @@
|
||||
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 */; };
|
||||
D2FB151B23A2B65B00C20E10 /* MoleculeContainer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */; };
|
||||
D2FB151D23A40F1500C20E10 /* StackItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2FB151C23A40F1500C20E10 /* StackItem.swift */; };
|
||||
DB06250B2293456500B72DD3 /* LeftRightLabelView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */; };
|
||||
DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; };
|
||||
DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; };
|
||||
@ -353,6 +356,7 @@
|
||||
D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUISwitch.m; sourceTree = "<group>"; };
|
||||
D22D1F542204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIStackableViewController.h; sourceTree = "<group>"; };
|
||||
D22D1F552204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIStackableViewController.m; sourceTree = "<group>"; };
|
||||
D243859823A16B1800332775 /* Container.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Container.swift; sourceTree = "<group>"; };
|
||||
D260D7AF22D65BDD007E7233 /* MVMCoreUIPageControl.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIPageControl.h; sourceTree = "<group>"; };
|
||||
D260D7B022D65BDD007E7233 /* MVMCoreUIPageControl.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIPageControl.m; sourceTree = "<group>"; };
|
||||
D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIPagingProtocol.h; sourceTree = "<group>"; };
|
||||
@ -508,6 +512,8 @@
|
||||
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>"; };
|
||||
D2F4DDE52371A4CB00CD28BB /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = "<group>"; };
|
||||
D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeContainer.swift; sourceTree = "<group>"; };
|
||||
D2FB151C23A40F1500C20E10 /* StackItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StackItem.swift; sourceTree = "<group>"; };
|
||||
DB06250A2293456500B72DD3 /* LeftRightLabelView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeftRightLabelView.swift; sourceTree = "<group>"; };
|
||||
DB891E822253FA8500022516 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = "<group>"; };
|
||||
DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = "<group>"; };
|
||||
@ -724,6 +730,7 @@
|
||||
D224799A231965AD003FCCF9 /* AccordionMoleculeTableViewCell.swift */,
|
||||
D27CD40D2322EEAF00C1DC07 /* TabsTableViewCell.swift */,
|
||||
D268C70D238C22D7007F2C1C /* DropDownFilterTableViewCell.swift */,
|
||||
D2FB151C23A40F1500C20E10 /* StackItem.swift */,
|
||||
);
|
||||
path = Items;
|
||||
sourceTree = "<group>";
|
||||
@ -831,6 +838,7 @@
|
||||
D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */,
|
||||
0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */,
|
||||
017BEB372360C6AC0024EF95 /* RadioButtonLabel.swift */,
|
||||
D2FB151A23A2B65B00C20E10 /* MoleculeContainer.swift */,
|
||||
017BEB47236230DB0024EF95 /* MoleculeViewProtocol.swift */,
|
||||
017BEB49236235BA0024EF95 /* ModelMoleculeViewProtocol.swift */,
|
||||
);
|
||||
@ -879,6 +887,7 @@
|
||||
D29DF2B721E7BE79003B2FB9 /* TabBarController */,
|
||||
D29DF2B621E7BE66003B2FB9 /* SplitViewController */,
|
||||
D2B18B93236214AD00A9AEDC /* NavigationController.swift */,
|
||||
D243859823A16B1800332775 /* Container.swift */,
|
||||
);
|
||||
path = Containers;
|
||||
sourceTree = "<group>";
|
||||
@ -1300,6 +1309,7 @@
|
||||
DBC4391922442197001AB423 /* DashLine.swift in Sources */,
|
||||
0AA33B34239813C50067DD0F /* UIColor+Extension.swift in Sources */,
|
||||
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */,
|
||||
D2FB151D23A40F1500C20E10 /* StackItem.swift in Sources */,
|
||||
D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */,
|
||||
0116A4E5228B19640094F3ED /* RadioButtonModel.swift in Sources */,
|
||||
017BEB48236230DB0024EF95 /* MoleculeViewProtocol.swift in Sources */,
|
||||
@ -1399,6 +1409,7 @@
|
||||
D2A6390122CBB1820052ED1F /* Carousel.swift in Sources */,
|
||||
D29DF2C721E7BF57003B2FB9 /* MFTabBarInteractor.m in Sources */,
|
||||
D29DF29521E7ADB8003B2FB9 /* ProgrammaticScrollViewController.m in Sources */,
|
||||
D2FB151B23A2B65B00C20E10 /* MoleculeContainer.swift in Sources */,
|
||||
D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */,
|
||||
012CA9DE2388723E003F810F /* ListPageTemplateModel.swift in Sources */,
|
||||
D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */,
|
||||
@ -1416,6 +1427,7 @@
|
||||
D27CD4102339057800C1DC07 /* EyebrowHeadlineBodyLink.swift in Sources */,
|
||||
D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */,
|
||||
0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */,
|
||||
D243859923A16B1800332775 /* Container.swift in Sources */,
|
||||
D29DF29821E7ADB8003B2FB9 /* MFScrollingViewController.m in Sources */,
|
||||
D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */,
|
||||
01EB369323609801006832FA /* HeaderModel.swift in Sources */,
|
||||
|
||||
@ -136,7 +136,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol, MVMCoreUI
|
||||
return true
|
||||
}
|
||||
|
||||
open func alignment() -> UIStackView.Alignment {
|
||||
open func horizontalAlignment() -> UIStackView.Alignment {
|
||||
return UIStackView.Alignment.leading;
|
||||
}
|
||||
|
||||
|
||||
@ -156,7 +156,7 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (UIStackViewAlignment)alignment {
|
||||
- (UIStackViewAlignment)horizontalAlignment {
|
||||
return UIStackViewAlignmentLeading;
|
||||
}
|
||||
|
||||
|
||||
@ -664,6 +664,8 @@
|
||||
}
|
||||
|
||||
- (void)setAsMolecule {
|
||||
self.translatesAutoresizingMaskIntoConstraints = false;
|
||||
[self pinHeight];
|
||||
[self setAsStandardCustom];
|
||||
}
|
||||
|
||||
@ -713,6 +715,10 @@
|
||||
[self setWithActionMap:json delegateObject:delegateObject additionalData:additionalData];
|
||||
}
|
||||
|
||||
- (UIStackViewAlignment)horizontalAlignment {
|
||||
return UIStackViewAlignmentCenter;
|
||||
}
|
||||
|
||||
#pragma mark - Handling Validations
|
||||
|
||||
- (void)setEnabledByValidity {
|
||||
|
||||
@ -154,7 +154,7 @@ extension CaretView: MVMCoreUIViewConstrainingProtocol {
|
||||
return true
|
||||
}
|
||||
|
||||
open func alignment() -> UIStackView.Alignment {
|
||||
open func horizontalAlignment() -> UIStackView.Alignment {
|
||||
return UIStackView.Alignment.leading;
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,11 +11,13 @@ import MVMCore
|
||||
/**
|
||||
This class expects its height and width to be equal.
|
||||
*/
|
||||
@objcMembers open class Checkbox: UIControl, MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol, MVMCoreUIViewConstrainingProtocol {
|
||||
@objcMembers open class Checkbox: Control, MVMCoreUIViewConstrainingProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public var sizeObject: MFSizeObject? = MFSizeObject(standardSize: Checkbox.defaultHeightWidth, standardiPadPortraitSize: Checkbox.defaultHeightWidth + 6.0)
|
||||
|
||||
// Form Validation
|
||||
var isRequired = false
|
||||
var fieldKey: String?
|
||||
@ -117,8 +119,8 @@ import MVMCore
|
||||
// MARK: - Constraints
|
||||
//--------------------------------------------------
|
||||
|
||||
private var heightConstraint: NSLayoutConstraint?
|
||||
private var widthConstraint: NSLayoutConstraint?
|
||||
public var heightConstraint: NSLayoutConstraint?
|
||||
public var widthConstraint: NSLayoutConstraint?
|
||||
|
||||
/// Updates the height and width anchors of the Checkbox with the assigned value.
|
||||
public var heigthWidthConstant: CGFloat = Checkbox.defaultHeightWidth {
|
||||
@ -138,7 +140,6 @@ import MVMCore
|
||||
accessibilityTraits = .button
|
||||
accessibilityHint = MVMCoreUIUtility.hardcodedString(withKey: "checkbox_action_hint")
|
||||
updateAccessibilityLabel()
|
||||
setupView()
|
||||
}
|
||||
|
||||
/// There is currently no intention on using xib files.
|
||||
@ -147,7 +148,7 @@ import MVMCore
|
||||
fatalError("xib file is not implemented for Checkbox.")
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
public convenience override init() {
|
||||
self.init(frame:.zero)
|
||||
}
|
||||
|
||||
@ -180,7 +181,8 @@ import MVMCore
|
||||
layer.borderColor = borderColor.cgColor
|
||||
}
|
||||
|
||||
open func setupView() {
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
|
||||
guard constraints.isEmpty else { return }
|
||||
|
||||
@ -349,18 +351,7 @@ import MVMCore
|
||||
|
||||
open override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
|
||||
|
||||
sendActions(for: touchIsAcceptablyOutside(touches.first) ? .touchUpOutside : .touchUpInside)
|
||||
}
|
||||
|
||||
func touchIsAcceptablyOutside(_ touch: UITouch?) -> Bool {
|
||||
let endLocation = touch?.location(in: self)
|
||||
let x = endLocation?.x ?? 0.0
|
||||
let y = endLocation?.y ?? 0.0
|
||||
let faultTolerance: CGFloat = 20.0
|
||||
let widthLimit = CGFloat(bounds.size.width + faultTolerance)
|
||||
let heightLimt = CGFloat(bounds.size.height + faultTolerance)
|
||||
|
||||
return x < -faultTolerance || y < -faultTolerance || x > widthLimit || y > heightLimt
|
||||
sendActions(for: .touchUpInside)
|
||||
}
|
||||
|
||||
override open func accessibilityActivate() -> Bool {
|
||||
@ -376,7 +367,8 @@ import MVMCore
|
||||
return true
|
||||
}
|
||||
|
||||
open func reset() {
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
|
||||
isEnabled(true)
|
||||
shapeLayer?.removeAllAnimations()
|
||||
@ -396,17 +388,24 @@ import MVMCore
|
||||
setupView()
|
||||
}
|
||||
|
||||
public func updateView(_ size: CGFloat) {
|
||||
public override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
if let dimension = sizeObject?.getValueBased(onSize: size) {
|
||||
widthConstraint?.constant = dimension
|
||||
heightConstraint?.constant = dimension
|
||||
}
|
||||
|
||||
layoutIfNeeded()
|
||||
}
|
||||
|
||||
public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
public override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
self.delegateObject = delegateObject
|
||||
FormValidator.setupValidation(molecule: self, delegate: delegateObject?.formValidationProtocol)
|
||||
|
||||
guard let dictionary = json else { return }
|
||||
|
||||
|
||||
groupName = dictionary.optionalStringForKey("groupName")
|
||||
fieldValue = dictionary.optionalStringForKey("value")
|
||||
if let fieldKey = dictionary[KeyFieldKey] as? String {
|
||||
@ -463,7 +462,7 @@ import MVMCore
|
||||
|
||||
// MARK:- FormValidationProtocol
|
||||
extension Checkbox: FormValidationFormFieldProtocol {
|
||||
|
||||
|
||||
public func formFieldGroupName() -> String? {
|
||||
return groupName
|
||||
}
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
//
|
||||
|
||||
|
||||
@objcMembers open class CheckboxWithLabelView: ViewConstrainingView {
|
||||
@objcMembers open class CheckboxWithLabelView: View {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Outlets
|
||||
//--------------------------------------------------
|
||||
@ -19,9 +19,7 @@
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
var sizeObject: MFSizeObject? = MFSizeObject(standardSize: Checkbox.defaultHeightWidth, standardiPadPortraitSize: Checkbox.defaultHeightWidth + 6.0)
|
||||
|
||||
var checkboxPosition: CheckboxPosition = .center
|
||||
public var checkboxPosition: CheckboxPosition = .center
|
||||
|
||||
public enum CheckboxPosition: String {
|
||||
case center
|
||||
@ -32,13 +30,10 @@
|
||||
//--------------------------------------------------
|
||||
// MARK: - Constraints
|
||||
//--------------------------------------------------
|
||||
|
||||
var checkboxWidthConstraint: NSLayoutConstraint?
|
||||
var checkboxHeightConstraint: NSLayoutConstraint?
|
||||
var checkboxTopConstraint: NSLayoutConstraint?
|
||||
var checkboxBottomConstraint: NSLayoutConstraint?
|
||||
var checkboxCenterYConstraint: NSLayoutConstraint?
|
||||
var centerLabelCheckboxConstraint: NSLayoutConstraint?
|
||||
|
||||
public var checkboxTopConstraint: NSLayoutConstraint?
|
||||
public var checkboxBottomConstraint: NSLayoutConstraint?
|
||||
public var checkboxCenterYConstraint: NSLayoutConstraint?
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Life Cycle
|
||||
@ -49,32 +44,20 @@
|
||||
|
||||
guard subviews.isEmpty else { return }
|
||||
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
|
||||
addSubview(checkbox)
|
||||
addSubview(label)
|
||||
|
||||
label.text = ""
|
||||
|
||||
let dimension = sizeObject?.getValueBasedOnApplicationWidth() ?? Checkbox.defaultHeightWidth
|
||||
checkboxWidthConstraint = checkbox.heightAnchor.constraint(equalToConstant: dimension)
|
||||
checkboxWidthConstraint?.isActive = true
|
||||
checkboxHeightConstraint = checkbox.widthAnchor.constraint(equalToConstant: dimension)
|
||||
checkboxHeightConstraint?.isActive = true
|
||||
|
||||
checkbox.leadingAnchor.constraint(equalTo: layoutMarginsGuide.leadingAnchor).isActive = true
|
||||
checkbox.topAnchor.constraint(greaterThanOrEqualTo: layoutMarginsGuide.topAnchor).isActive = true
|
||||
layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: checkbox.bottomAnchor).isActive = true
|
||||
|
||||
let checboxBottom = checkbox.bottomAnchor.constraint(equalTo: layoutMarginsGuide.bottomAnchor)
|
||||
checboxBottom.priority = UILayoutPriority(249)
|
||||
checboxBottom.isActive = true
|
||||
|
||||
// Allows various positions of checkbox.
|
||||
checkboxBottomConstraint = layoutMarginsGuide.bottomAnchor.constraint(equalTo: checkbox.bottomAnchor)
|
||||
checkboxBottomConstraint?.isActive = true
|
||||
|
||||
checkboxTopConstraint = checkbox.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor)
|
||||
checkboxTopConstraint?.isActive = true
|
||||
|
||||
checkboxCenterYConstraint = checkbox.centerYAnchor.constraint(equalTo: centerYAnchor)
|
||||
centerLabelCheckboxConstraint = label.centerYAnchor.constraint(equalTo: checkbox.centerYAnchor)
|
||||
|
||||
label.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true
|
||||
layoutMarginsGuide.trailingAnchor.constraint(equalTo: label.trailingAnchor).isActive = true
|
||||
@ -82,7 +65,7 @@
|
||||
|
||||
layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: label.bottomAnchor).isActive = true
|
||||
let bottomLabelConstraint = layoutMarginsGuide.bottomAnchor.constraint(equalTo: label.bottomAnchor)
|
||||
bottomLabelConstraint.priority = UILayoutPriority(249)
|
||||
bottomLabelConstraint.priority = .defaultLow
|
||||
bottomLabelConstraint.isActive = true
|
||||
|
||||
alignCheckbox(.center)
|
||||
@ -92,17 +75,12 @@
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
fatalError("xib file is not implemented for CheckboxWithLabelView")
|
||||
}
|
||||
|
||||
override public init(frame: CGRect) {
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setupView()
|
||||
}
|
||||
|
||||
public convenience init() {
|
||||
public convenience override init() {
|
||||
self.init(frame: .zero)
|
||||
}
|
||||
|
||||
@ -112,6 +90,11 @@
|
||||
alignCheckbox(position)
|
||||
}
|
||||
|
||||
required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
fatalError("xib file is not implemented for CheckboxWithLabelView")
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//--------------------------------------------------
|
||||
@ -125,64 +108,41 @@
|
||||
checkboxBottomConstraint?.isActive = false
|
||||
checkboxTopConstraint?.isActive = false
|
||||
checkboxCenterYConstraint?.isActive = true
|
||||
centerLabelCheckboxConstraint?.isActive = true
|
||||
|
||||
case .top:
|
||||
checkboxBottomConstraint?.isActive = false
|
||||
checkboxTopConstraint?.isActive = true
|
||||
checkboxCenterYConstraint?.isActive = false
|
||||
centerLabelCheckboxConstraint?.isActive = false
|
||||
|
||||
case .bottom:
|
||||
checkboxBottomConstraint?.isActive = true
|
||||
checkboxTopConstraint?.isActive = false
|
||||
checkboxCenterYConstraint?.isActive = false
|
||||
centerLabelCheckboxConstraint?.isActive = false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// MARK: - Molecular
|
||||
// MARK: - Molecular
|
||||
extension CheckboxWithLabelView {
|
||||
|
||||
override open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
return CGFloat(Checkbox.defaultHeightWidth)
|
||||
open class func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
return 200
|
||||
}
|
||||
|
||||
@objc override open func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
|
||||
label.updateView(size)
|
||||
|
||||
if self.checkbox.responds(to: #selector(self.updateView(_:))) {
|
||||
if let dimension = sizeObject?.getValueBased(onSize: size) {
|
||||
checkboxWidthConstraint?.constant = dimension
|
||||
checkboxHeightConstraint?.constant = dimension
|
||||
checkbox.updateView(size)
|
||||
}
|
||||
}
|
||||
|
||||
checkbox.updateView(size)
|
||||
layoutIfNeeded()
|
||||
}
|
||||
|
||||
override open func alignment() -> UIStackView.Alignment {
|
||||
return .leading
|
||||
}
|
||||
|
||||
open override func resetConstraints() {
|
||||
super.resetConstraints()
|
||||
|
||||
checkboxCenterYConstraint?.isActive = false
|
||||
checkboxBottomConstraint?.isActive = false
|
||||
checkboxTopConstraint?.isActive = false
|
||||
centerLabelCheckboxConstraint?.isActive = false
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
|
||||
label.text = ""
|
||||
checkbox.reset()
|
||||
alignCheckbox(.center)
|
||||
}
|
||||
|
||||
override open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
@ -705,7 +705,7 @@ extension Label {
|
||||
return true
|
||||
}
|
||||
|
||||
public func alignment() -> UIStackView.Alignment {
|
||||
public func horizontalAlignment() -> UIStackView.Alignment {
|
||||
return .leading
|
||||
}
|
||||
|
||||
|
||||
@ -193,7 +193,7 @@ const CGFloat SwitchShakeIntensity = 2;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (UIStackViewAlignment)alignment {
|
||||
- (UIStackViewAlignment)horizontalAlignment {
|
||||
return UIStackViewAlignmentTrailing;
|
||||
}
|
||||
|
||||
|
||||
@ -74,8 +74,9 @@ import Foundation
|
||||
if let thickness = json?.optionalCGFloatForKey("thickness") {
|
||||
self.thickness = thickness
|
||||
}
|
||||
if let percentage = json?["percent"] as? Float {
|
||||
progress = percentage/100.0
|
||||
// as? Float returns nil, apple defect.
|
||||
if let percentage = json?["percent"] as? CGFloat {
|
||||
progress = Float(percentage/100.0)
|
||||
}
|
||||
if let progressColor = json?.optionalStringForKey("progressColor") {
|
||||
progressTintColor = UIColor.mfGet(forHex: progressColor)
|
||||
|
||||
@ -8,28 +8,41 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
public class Control: UIControl, ModelMoleculeViewProtocol {
|
||||
var json: [AnyHashable: Any]?
|
||||
public var model: MoleculeProtocol?
|
||||
@objcMembers open class Control: UIControl, ModelMoleculeViewProtocol {
|
||||
//--------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//--------------------------------------------------
|
||||
|
||||
public var json: [AnyHashable: Any]?
|
||||
public var model: MoleculeProtocol?
|
||||
|
||||
private var initialSetupPerformed = false
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Initializers
|
||||
//--------------------------------------------------
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: .zero)
|
||||
initialSetup()
|
||||
}
|
||||
|
||||
init() {
|
||||
public init() {
|
||||
super.init(frame: .zero)
|
||||
initialSetup()
|
||||
}
|
||||
|
||||
public required init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
initialSetup()
|
||||
fatalError("Control does not support xib.")
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - Setup
|
||||
//--------------------------------------------------
|
||||
|
||||
public func initialSetup() {
|
||||
|
||||
if !initialSetupPerformed {
|
||||
initialSetupPerformed = true
|
||||
setupView()
|
||||
@ -39,11 +52,25 @@ public class Control: UIControl, ModelMoleculeViewProtocol {
|
||||
public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
||||
self.model = model
|
||||
}
|
||||
|
||||
//--------------------------------------------------
|
||||
// MARK: - UITouch
|
||||
//--------------------------------------------------
|
||||
|
||||
override open func point(inside point: CGPoint, with event: UIEvent?) -> Bool {
|
||||
|
||||
// If the control is smaller than 44pt by width or height, this will compensate.
|
||||
let faultToleranceX: CGFloat = max((MinimumTappableArea - bounds.size.width) / 2.0, 0)
|
||||
let faultToleranceY: CGFloat = max((MinimumTappableArea - bounds.size.height) / 2.0, 0)
|
||||
let area = bounds.insetBy(dx: -faultToleranceX, dy: -faultToleranceY)
|
||||
return area.contains(point)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
extension Control: MVMCoreViewProtocol {
|
||||
public func updateView(_ size: CGFloat) {
|
||||
}
|
||||
|
||||
public func updateView(_ size: CGFloat) {}
|
||||
|
||||
/// Will be called only once.
|
||||
public func setupView() {
|
||||
@ -52,8 +79,9 @@ extension Control: MVMCoreViewProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
extension Control: MVMCoreUIMoleculeViewProtocol {
|
||||
public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
self.json = json
|
||||
|
||||
if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) {
|
||||
|
||||
239
MVMCoreUI/Containers/Container.swift
Normal file
239
MVMCoreUI/Containers/Container.swift
Normal file
@ -0,0 +1,239 @@
|
||||
//
|
||||
// Container.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 12/11/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
public protocol ContainerModelProtocol {
|
||||
var horizontalAlignment: UIStackView.Alignment? { get set }
|
||||
var verticalAlignment: UIStackView.Alignment? { get set }
|
||||
var useHorizontalMargins: Bool? { get set }
|
||||
var useVerticalMargins: Bool? { get set }
|
||||
}
|
||||
|
||||
public class ContainerHelper: NSObject {
|
||||
var leftConstraint: NSLayoutConstraint?
|
||||
var topConstraint: NSLayoutConstraint?
|
||||
var bottomConstraint: NSLayoutConstraint?
|
||||
var rightConstraint: NSLayoutConstraint?
|
||||
|
||||
var alignCenterHorizontalConstraint: NSLayoutConstraint?
|
||||
var alignCenterLeftConstraint: NSLayoutConstraint?
|
||||
var alignCenterRightConstraint: NSLayoutConstraint?
|
||||
|
||||
var alignCenterVerticalConstraint: NSLayoutConstraint?
|
||||
var alignCenterTopConstraint: NSLayoutConstraint?
|
||||
var alignCenterBottomConstraint: NSLayoutConstraint?
|
||||
|
||||
var leftLowConstraint: NSLayoutConstraint?
|
||||
var topLowConstraint: NSLayoutConstraint?
|
||||
var bottomLowConstraint: NSLayoutConstraint?
|
||||
var rightLowConstraint: NSLayoutConstraint?
|
||||
|
||||
func constrainView(_ view: UIView) {
|
||||
guard let margins = view.superview?.layoutMarginsGuide else { return }
|
||||
leftConstraint = view.leftAnchor.constraint(equalTo: margins.leftAnchor)
|
||||
leftConstraint?.isActive = true
|
||||
|
||||
topConstraint = view.topAnchor.constraint(equalTo: margins.topAnchor)
|
||||
topConstraint?.isActive = true
|
||||
|
||||
rightConstraint = margins.rightAnchor.constraint(equalTo: view.rightAnchor)
|
||||
rightConstraint?.isActive = true
|
||||
|
||||
bottomConstraint = margins.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
||||
bottomConstraint?.isActive = true
|
||||
|
||||
alignCenterHorizontalConstraint = view.centerXAnchor.constraint(equalTo: margins.centerXAnchor)
|
||||
alignCenterLeftConstraint = view.leftAnchor.constraint(greaterThanOrEqualTo: margins.leftAnchor)
|
||||
alignCenterRightConstraint = margins.rightAnchor.constraint(greaterThanOrEqualTo: view.rightAnchor)
|
||||
|
||||
alignCenterVerticalConstraint = view.centerYAnchor.constraint(equalTo: margins.centerYAnchor)
|
||||
alignCenterTopConstraint = view.topAnchor.constraint(greaterThanOrEqualTo: margins.topAnchor)
|
||||
alignCenterBottomConstraint = margins.bottomAnchor.constraint(greaterThanOrEqualTo: view.bottomAnchor)
|
||||
|
||||
leftLowConstraint = view.leftAnchor.constraint(equalTo: margins.leftAnchor)
|
||||
leftLowConstraint?.priority = UILayoutPriority(rawValue: 200)
|
||||
leftLowConstraint?.isActive = true
|
||||
|
||||
topLowConstraint = view.topAnchor.constraint(equalTo: margins.topAnchor)
|
||||
topLowConstraint?.priority = UILayoutPriority(rawValue: 200)
|
||||
topLowConstraint?.isActive = true
|
||||
|
||||
rightLowConstraint = margins.rightAnchor.constraint(equalTo: view.rightAnchor)
|
||||
rightLowConstraint?.priority = UILayoutPriority(rawValue: 200)
|
||||
rightLowConstraint?.isActive = true
|
||||
|
||||
bottomLowConstraint = margins.bottomAnchor.constraint(equalTo: view.bottomAnchor)
|
||||
bottomLowConstraint?.priority = UILayoutPriority(rawValue: 200)
|
||||
bottomLowConstraint?.isActive = true
|
||||
|
||||
setAccessibility(view)
|
||||
}
|
||||
|
||||
func setAccessibility(_ view: UIView) {
|
||||
guard let superView = view.superview else { return }
|
||||
superView.isAccessibilityElement = false
|
||||
if let elements = view.accessibilityElements {
|
||||
superView.accessibilityElements = elements
|
||||
} else {
|
||||
superView.accessibilityElements = [view]
|
||||
}
|
||||
}
|
||||
|
||||
func alignHorizontal(_ alignment: UIStackView.Alignment) {
|
||||
switch alignment {
|
||||
case .center:
|
||||
alignCenterHorizontalConstraint?.isActive = true
|
||||
alignCenterLeftConstraint?.isActive = true
|
||||
alignCenterRightConstraint?.isActive = true
|
||||
leftConstraint?.isActive = false
|
||||
rightConstraint?.isActive = false
|
||||
case .leading:
|
||||
alignCenterHorizontalConstraint?.isActive = false
|
||||
alignCenterLeftConstraint?.isActive = false
|
||||
alignCenterRightConstraint?.isActive = true
|
||||
leftConstraint?.isActive = true
|
||||
rightConstraint?.isActive = false
|
||||
case .trailing:
|
||||
alignCenterHorizontalConstraint?.isActive = false
|
||||
alignCenterLeftConstraint?.isActive = true
|
||||
alignCenterRightConstraint?.isActive = false
|
||||
leftConstraint?.isActive = false
|
||||
rightConstraint?.isActive = true
|
||||
case .fill:
|
||||
alignCenterHorizontalConstraint?.isActive = false
|
||||
alignCenterLeftConstraint?.isActive = false
|
||||
alignCenterRightConstraint?.isActive = false
|
||||
leftConstraint?.isActive = true
|
||||
rightConstraint?.isActive = true
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
func alignVertical(_ alignment: UIStackView.Alignment) {
|
||||
switch alignment {
|
||||
case .center:
|
||||
alignCenterVerticalConstraint?.isActive = true
|
||||
alignCenterTopConstraint?.isActive = true
|
||||
alignCenterBottomConstraint?.isActive = true
|
||||
topConstraint?.isActive = false
|
||||
bottomConstraint?.isActive = false
|
||||
case .leading:
|
||||
alignCenterVerticalConstraint?.isActive = false
|
||||
alignCenterTopConstraint?.isActive = false
|
||||
alignCenterBottomConstraint?.isActive = true
|
||||
topConstraint?.isActive = true
|
||||
bottomConstraint?.isActive = false
|
||||
case .trailing:
|
||||
alignCenterVerticalConstraint?.isActive = false
|
||||
alignCenterTopConstraint?.isActive = true
|
||||
alignCenterBottomConstraint?.isActive = false
|
||||
topConstraint?.isActive = false
|
||||
bottomConstraint?.isActive = true
|
||||
case .fill:
|
||||
alignCenterVerticalConstraint?.isActive = false
|
||||
alignCenterTopConstraint?.isActive = false
|
||||
alignCenterBottomConstraint?.isActive = false
|
||||
topConstraint?.isActive = true
|
||||
bottomConstraint?.isActive = true
|
||||
default: break
|
||||
}
|
||||
}
|
||||
|
||||
func set(with model: ContainerModelProtocol) {
|
||||
if let horizontalAlignment = model.horizontalAlignment {
|
||||
alignHorizontal(horizontalAlignment)
|
||||
}
|
||||
if let verticalAlignment = model.verticalAlignment {
|
||||
alignVertical(verticalAlignment)
|
||||
}
|
||||
}
|
||||
|
||||
static func getAlignment(for string: String) -> UIStackView.Alignment? {
|
||||
switch string {
|
||||
case "leading":
|
||||
return .leading
|
||||
case "trailing":
|
||||
return .trailing
|
||||
case "center":
|
||||
return .center
|
||||
case "fill":
|
||||
return .fill
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func set(with JSON: [AnyHashable: Any]?, for contained: UIView) {
|
||||
if let horizontalAlignmentString = JSON?.optionalStringForKey("horizontalAlignment"), let alignment = ContainerHelper.getAlignment(for: horizontalAlignmentString) ?? (contained as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() {
|
||||
alignHorizontal(alignment)
|
||||
} else if let alignment = (contained as? MVMCoreUIViewConstrainingProtocol)?.horizontalAlignment?() {
|
||||
alignHorizontal(alignment)
|
||||
}
|
||||
|
||||
if let verticalAlignmentString = JSON?.optionalStringForKey("verticalAlignment"), let alignment = ContainerHelper.getAlignment(for: verticalAlignmentString) ?? (contained as? MVMCoreUIViewConstrainingProtocol)?.verticalAlignment?() {
|
||||
alignVertical(alignment)
|
||||
} else if let alignment = (contained as? MVMCoreUIViewConstrainingProtocol)?.verticalAlignment?() {
|
||||
alignVertical(alignment)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open class Container: View {
|
||||
var containerModel: ContainerModelProtocol?
|
||||
var view: UIView?
|
||||
let containerHelper = ContainerHelper()
|
||||
|
||||
var topMarginPadding: CGFloat = 0
|
||||
var bottomMarginPadding: CGFloat = 0
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
public extension Container {
|
||||
override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
(view as? MVMCoreViewProtocol)?.updateView(size)
|
||||
MFStyler.setMarginsFor(self, size: size, defaultHorizontal: containerModel?.useHorizontalMargins ?? true, top: containerModel?.useHorizontalMargins ?? true ? topMarginPadding : 0, bottom: containerModel?.useHorizontalMargins ?? true ? bottomMarginPadding : 0)
|
||||
}
|
||||
|
||||
/// Will be called only once.
|
||||
override func setupView() {
|
||||
super.setupView()
|
||||
backgroundColor = .clear
|
||||
}
|
||||
|
||||
func addAndContain(_ view: UIView) {
|
||||
view.translatesAutoresizingMaskIntoConstraints = false
|
||||
addSubview(view)
|
||||
containerHelper.constrainView(view)
|
||||
self.view = view
|
||||
}
|
||||
|
||||
convenience init(andContain view: UIView) {
|
||||
self.init()
|
||||
addAndContain(view)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
public extension Container {
|
||||
override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
guard let view = view else { return }
|
||||
containerHelper.set(with: json, for: view)
|
||||
}
|
||||
|
||||
override func reset() {
|
||||
super.reset()
|
||||
(view as? MVMCoreUIMoleculeViewProtocol)?.reset?()
|
||||
}
|
||||
|
||||
override func setAsMolecule() {
|
||||
(view as? MVMCoreUIMoleculeViewProtocol)?.setAsMolecule?()
|
||||
}
|
||||
}
|
||||
@ -54,7 +54,7 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (UIStackViewAlignment)alignment {
|
||||
- (UIStackViewAlignment)horizontalAlignment {
|
||||
return UIStackViewAlignmentLeading;
|
||||
}
|
||||
|
||||
|
||||
@ -18,16 +18,14 @@ import Foundation
|
||||
public var percentage: Int?
|
||||
public var verticalAlignment: String?
|
||||
public var horizontalAlignment: String?
|
||||
public var gone: Bool? = false
|
||||
public var gone: Bool?
|
||||
public var useHorizontalMargins: Bool?
|
||||
public var useVerticalMargins: Bool?
|
||||
|
||||
public init(molecule: MoleculeProtocol?, spacing: CGFloat?, percentage: Int?, verticalAlignment: String?, horizontalAlignment: String?, gone: Bool = false) {
|
||||
public init(molecule: MoleculeProtocol) {
|
||||
self.molecule = molecule
|
||||
self.spacing = spacing
|
||||
self.percentage = percentage
|
||||
self.verticalAlignment = verticalAlignment
|
||||
self.horizontalAlignment = horizontalAlignment
|
||||
self.gone = gone
|
||||
}
|
||||
|
||||
enum CodingKeys: String, CodingKey {
|
||||
case moleculeName
|
||||
case molecule
|
||||
@ -37,6 +35,8 @@ import Foundation
|
||||
case verticalAlignment
|
||||
case horizontalAlignment
|
||||
case gone
|
||||
case useHorizontalMargins
|
||||
case useVerticalMargins
|
||||
}
|
||||
|
||||
required public init(from decoder: Decoder) throws {
|
||||
@ -49,6 +49,8 @@ import Foundation
|
||||
self.verticalAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .verticalAlignment)
|
||||
self.horizontalAlignment = try typeContainer.decodeIfPresent(String.self, forKey: .horizontalAlignment)
|
||||
self.gone = try typeContainer.decodeIfPresent(Bool.self, forKey: .gone)
|
||||
self.useHorizontalMargins = try typeContainer.decodeIfPresent(Bool.self, forKey: .useHorizontalMargins)
|
||||
self.useVerticalMargins = try typeContainer.decodeIfPresent(Bool.self, forKey: .useVerticalMargins)
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
@ -60,5 +62,7 @@ import Foundation
|
||||
try container.encodeIfPresent(verticalAlignment, forKey: .verticalAlignment)
|
||||
try container.encodeIfPresent(horizontalAlignment, forKey: .horizontalAlignment)
|
||||
try container.encodeIfPresent(gone, forKey: .gone)
|
||||
try container.encodeIfPresent(useHorizontalMargins, forKey: .useHorizontalMargins)
|
||||
try container.encodeIfPresent(useVerticalMargins, forKey: .useVerticalMargins)
|
||||
}
|
||||
}
|
||||
|
||||
@ -12,7 +12,8 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi
|
||||
|
||||
open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)?
|
||||
open var json: [AnyHashable: Any]?
|
||||
|
||||
public let containerHelper = ContainerHelper()
|
||||
|
||||
// In updateView, will set padding to default.
|
||||
open var updateViewHorizontalDefaults = true
|
||||
open var updateViewVerticalDefaults = true
|
||||
@ -93,19 +94,17 @@ open class MoleculeCollectionViewCell: UICollectionViewCell, MVMCoreUIMoleculeVi
|
||||
if molecule == nil {
|
||||
if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(collectionModel.molecule, delegateObject, true) {
|
||||
contentView.insertSubview(moleculeView, at: 0)
|
||||
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: true).values))
|
||||
containerHelper.constrainView(moleculeView)
|
||||
molecule = moleculeView
|
||||
}
|
||||
} else {
|
||||
(molecule as? ModelMoleculeViewProtocol)?.setWithModel(collectionModel.molecule, delegateObject, additionalData)
|
||||
}
|
||||
|
||||
// This molecule will handle spacing by default.
|
||||
if let castView = molecule as? MVMCoreUIViewConstrainingProtocol {
|
||||
castView.shouldSetHorizontalMargins?(false)
|
||||
castView.shouldSetVerticalMargins?(false)
|
||||
}
|
||||
accessibilityElements = molecule?.subviews
|
||||
guard let molecule = molecule else { return }
|
||||
containerHelper.set(with: json, for: molecule)
|
||||
|
||||
accessibilityElements = molecule.subviews
|
||||
}
|
||||
|
||||
public func reset() {
|
||||
|
||||
@ -9,7 +9,8 @@
|
||||
import UIKit
|
||||
|
||||
@objcMembers open class MoleculeTableViewCell: TableViewCell {
|
||||
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
public override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
||||
super.setWithModel(model, delegateObject, additionalData)
|
||||
|
||||
|
||||
54
MVMCoreUI/Molecules/Items/StackItem.swift
Normal file
54
MVMCoreUI/Molecules/Items/StackItem.swift
Normal file
@ -0,0 +1,54 @@
|
||||
//
|
||||
// StackItem.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 12/13/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
open class StackItemView: MoleculeContainer {
|
||||
}
|
||||
|
||||
open class StackItemModel: ContainerModelProtocol {
|
||||
public var view: StackItemView
|
||||
public var spacing: CGFloat?
|
||||
public var percentage: Int?
|
||||
public var verticalAlignment: UIStackView.Alignment?
|
||||
public var horizontalAlignment: UIStackView.Alignment?
|
||||
public var useHorizontalMargins: Bool? = false
|
||||
public var useVerticalMargins: Bool? = false
|
||||
public var gone = false
|
||||
|
||||
init(with view: StackItemView) {
|
||||
self.view = view
|
||||
view.containerModel = self
|
||||
}
|
||||
|
||||
init(with view: StackItemView, stackItemModel: MoleculeStackItemModel?) {
|
||||
self.view = view
|
||||
update(with: stackItemModel)
|
||||
}
|
||||
|
||||
func update(with stackItemModel: MoleculeStackItemModel?) {
|
||||
gone = stackItemModel?.gone ?? false
|
||||
spacing = stackItemModel?.spacing
|
||||
percentage = stackItemModel?.percentage
|
||||
|
||||
if let alignment = stackItemModel?.verticalAlignment {
|
||||
verticalAlignment = ContainerHelper.getAlignment(for: alignment)
|
||||
} else {
|
||||
verticalAlignment = nil
|
||||
}
|
||||
if let alignment = stackItemModel?.horizontalAlignment {
|
||||
horizontalAlignment = ContainerHelper.getAlignment(for: alignment)
|
||||
} else {
|
||||
horizontalAlignment = nil
|
||||
}
|
||||
useHorizontalMargins = stackItemModel?.useHorizontalMargins ?? false
|
||||
useVerticalMargins = stackItemModel?.useVerticalMargins ?? false
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -11,9 +11,10 @@ import UIKit
|
||||
@objcMembers open class TableViewCell: UITableViewCell, MVMCoreUIMoleculeViewProtocol, MoleculeListCellProtocol, ModelMoleculeViewProtocol {
|
||||
|
||||
open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)?
|
||||
open var json: [AnyHashable: Any]?
|
||||
open var listItemModel: ListItemModel?
|
||||
open var json: [String: Any]?
|
||||
|
||||
public let containerHelper = ContainerHelper()
|
||||
|
||||
// In updateView, will set padding to default.
|
||||
open var updateViewHorizontalDefaults = true
|
||||
|
||||
@ -50,6 +51,8 @@ import UIKit
|
||||
styleStandard()
|
||||
case "header":
|
||||
styleHeader()
|
||||
case "sectionFooter":
|
||||
styleFooter()
|
||||
case "none":
|
||||
styleNone()
|
||||
default: break
|
||||
@ -70,6 +73,13 @@ import UIKit
|
||||
bottomSeparatorView?.style = .thin
|
||||
}
|
||||
|
||||
open func styleFooter() {
|
||||
topMarginPadding = 24
|
||||
bottomMarginPadding = 0
|
||||
topSeparatorView?.style = .none
|
||||
bottomSeparatorView?.style = .none
|
||||
}
|
||||
|
||||
open func styleNone() {
|
||||
topMarginPadding = 0
|
||||
bottomMarginPadding = 0
|
||||
@ -80,14 +90,7 @@ import UIKit
|
||||
/// Adds the molecule to the view.
|
||||
open func addMolecule(_ molecule: UIView & MVMCoreUIMoleculeViewProtocol) {
|
||||
contentView.addSubview(molecule)
|
||||
let standardConstraints = (molecule as? MVMCoreUIViewConstrainingProtocol)?.useStandardConstraints?() ?? true
|
||||
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: molecule, useMargins: standardConstraints).values))
|
||||
|
||||
// This molecule will by default handle margins.
|
||||
if let castView = molecule as? MVMCoreUIViewConstrainingProtocol {
|
||||
castView.shouldSetHorizontalMargins?(false)
|
||||
castView.shouldSetVerticalMargins?(false)
|
||||
}
|
||||
containerHelper.constrainView(molecule)
|
||||
self.molecule = molecule
|
||||
}
|
||||
|
||||
@ -178,14 +181,9 @@ import UIKit
|
||||
addSeparatorsIfNeeded()
|
||||
bottomSeparatorView?.setWithModel(separator, nil, nil)
|
||||
}
|
||||
|
||||
(molecule as? ModelMoleculeViewProtocol)?.setWithModel(model.molecule, delegateObject, additionalData)
|
||||
|
||||
// This molecule will by default handle margins.
|
||||
if let castView = molecule as? MVMCoreUIViewConstrainingProtocol {
|
||||
castView.shouldSetHorizontalMargins?(false)
|
||||
castView.shouldSetVerticalMargins?(false)
|
||||
}
|
||||
|
||||
guard let molecule = molecule else { return }
|
||||
containerHelper.set(with: json, for: molecule)
|
||||
}
|
||||
|
||||
public func reset() {
|
||||
@ -241,11 +239,13 @@ import UIKit
|
||||
|
||||
var queue = [UIView]()
|
||||
|
||||
for view in views {
|
||||
// Reversed the array to first check views at the front.
|
||||
for view in views.reversed() {
|
||||
// Only one Label will have a hero in a table cell.
|
||||
if let label = view as? Label, label.hero != nil {
|
||||
return label
|
||||
}
|
||||
|
||||
queue.append(contentsOf: view.subviews)
|
||||
}
|
||||
|
||||
|
||||
@ -8,13 +8,20 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
//struct ModuleMoleculeModel: ContainerModelProtocol {
|
||||
// var horizontalAlignment: UIStackView.Alignment? = .fill
|
||||
// var verticalAlignment: UIStackView.Alignment? = .fill
|
||||
// var useHorizontalMargins: Bool? = false
|
||||
// var useVerticalMargins: Bool? = false
|
||||
//}
|
||||
|
||||
open class ModuleMolecule: ViewConstrainingView, ModelMoleculeViewProtocol {
|
||||
|
||||
open var moduleMolecule: (UIView & MVMCoreUIMoleculeViewProtocol & ModelMoleculeViewProtocol)?
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
moduleMolecule?.updateView(size)
|
||||
public override func setupView() {
|
||||
super.setupView()
|
||||
//containerModel = ModuleMoleculeModel()
|
||||
}
|
||||
|
||||
public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String: AnyHashable]?) {
|
||||
@ -24,7 +31,7 @@ open class ModuleMolecule: ViewConstrainingView, ModelMoleculeViewProtocol {
|
||||
|
||||
guard let moduleMoleculeModel = model as? ModuleMoleculeModel,
|
||||
let moduleModel = delegateObject?.moduleProtocol?.getModuleWithName(moduleMoleculeModel.moduleName) as? MoleculeProtocol else {
|
||||
// Critical error
|
||||
// Critical error
|
||||
return
|
||||
}
|
||||
|
||||
@ -45,29 +52,17 @@ open class ModuleMolecule: ViewConstrainingView, ModelMoleculeViewProtocol {
|
||||
moduleMolecule?.setWithModel(model, delegateObject, additionalData)
|
||||
}
|
||||
}
|
||||
|
||||
open override func setAsMolecule() {
|
||||
super.setAsMolecule()
|
||||
moduleMolecule?.setAsMolecule?()
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
moduleMolecule?.reset?()
|
||||
}
|
||||
|
||||
|
||||
public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
guard let moduleName = json?.optionalStringForKey("moduleName"),
|
||||
let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
|
||||
guard let moduleName = json?.optionalStringForKey("moduleName"), let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
|
||||
// Critical error
|
||||
return 0
|
||||
}
|
||||
return MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: module)?.estimatedHeight?(forRow: module, delegateObject: delegateObject) ?? 0
|
||||
}
|
||||
|
||||
|
||||
public override class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||
guard let moduleName = molecule?.optionalStringForKey("moduleName"),
|
||||
let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
|
||||
guard let moduleName = molecule?.optionalStringForKey("moduleName"), let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
|
||||
// Critical error
|
||||
return "moduleMolecule<>"
|
||||
}
|
||||
@ -87,25 +82,4 @@ open class ModuleMolecule: ViewConstrainingView, ModelMoleculeViewProtocol {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIViewConstrainingProtocol
|
||||
open override func useStandardConstraints() -> Bool {
|
||||
return (moduleMolecule as? MVMCoreUIViewConstrainingProtocol)?.useStandardConstraints?() ?? true
|
||||
}
|
||||
|
||||
open override func alignHorizontal(_ alignment: UIStackView.Alignment) {
|
||||
(moduleMolecule as? MVMCoreUIViewConstrainingProtocol)?.alignHorizontal?(alignment)
|
||||
}
|
||||
|
||||
open override func alignVertical(_ alignment: UIStackView.Alignment) {
|
||||
(moduleMolecule as? MVMCoreUIViewConstrainingProtocol)?.alignVertical?(alignment)
|
||||
}
|
||||
|
||||
open override func shouldSetHorizontalMargins(_ shouldSet: Bool) {
|
||||
(moduleMolecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(shouldSet)
|
||||
}
|
||||
|
||||
open override func shouldSetVerticalMargins(_ shouldSet: Bool) {
|
||||
(moduleMolecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(shouldSet)
|
||||
}
|
||||
}
|
||||
|
||||
27
MVMCoreUI/Molecules/MoleculeContainer.swift
Normal file
27
MVMCoreUI/Molecules/MoleculeContainer.swift
Normal file
@ -0,0 +1,27 @@
|
||||
//
|
||||
// MoleculeContainer.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 12/12/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
open class MoleculeContainer: Container {
|
||||
|
||||
override public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule) else {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
return
|
||||
}
|
||||
if view == nil {
|
||||
if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: false) {
|
||||
addAndContain(molecule)
|
||||
}
|
||||
} else {
|
||||
(view as? MVMCoreUIMoleculeViewProtocol)?.setWithJSON?(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
@ -8,28 +8,23 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
open class StandardFooterView: ViewConstrainingView {
|
||||
open class StandardFooterView: MoleculeContainer {
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
topMarginPadding = PaddingDefaultVerticalSpacing
|
||||
bottomMarginPadding = PaddingDefaultVerticalSpacing
|
||||
shouldSetupMoleculeFromJSON = true
|
||||
updateViewVerticalDefaults = true
|
||||
updateViewHorizontalDefaults = true
|
||||
}
|
||||
|
||||
open override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
|
||||
// This molecule will by default handle margins.
|
||||
(molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(false)
|
||||
(molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(false)
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
if let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule), let height = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON)?.estimatedHeight?(forRow: moleculeJSON, delegateObject: delegateObject) {
|
||||
return height + PaddingDefaultVerticalSpacing + PaddingDefaultVerticalSpacing
|
||||
}
|
||||
return 42
|
||||
}
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
topMarginPadding = PaddingDefaultVerticalSpacing
|
||||
bottomMarginPadding = PaddingDefaultVerticalSpacing
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,7 +8,7 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
public class StandardHeaderView: ViewConstrainingView, ModelMoleculeViewProtocol {
|
||||
public class StandardHeaderView: MoleculeContainer {
|
||||
var line: Line?
|
||||
|
||||
// MARK: - MVMCoreViewProtocol
|
||||
@ -19,9 +19,6 @@ public class StandardHeaderView: ViewConstrainingView, ModelMoleculeViewProtocol
|
||||
|
||||
public override func setupView() {
|
||||
super.setupView()
|
||||
shouldSetupMoleculeFromJSON = true
|
||||
updateViewVerticalDefaults = true
|
||||
updateViewHorizontalDefaults = true
|
||||
topMarginPadding = PaddingDefaultVerticalSpacing
|
||||
bottomMarginPadding = PaddingDefaultVerticalSpacing
|
||||
|
||||
@ -38,25 +35,20 @@ public class StandardHeaderView: ViewConstrainingView, ModelMoleculeViewProtocol
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
|
||||
// This molecule will by default handle margins.
|
||||
(molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(false)
|
||||
(molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(false)
|
||||
|
||||
if let separatorJSON = json?.optionalDictionaryForKey("separator") {
|
||||
line?.setWithJSON(separatorJSON, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
|
||||
open func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
||||
open override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
||||
|
||||
#warning("This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.")
|
||||
//TODO: This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.
|
||||
setUpWithModel(model, delegateObject, additionalData)
|
||||
|
||||
// This molecule will by default handle margins.
|
||||
(molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(false)
|
||||
(molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(false)
|
||||
// setUpWithModel(model, delegateObject, additionalData)
|
||||
//
|
||||
// // This molecule will by default handle margins.
|
||||
// (molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(false)
|
||||
// (molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(false)
|
||||
|
||||
guard let headerModel = model as? HeaderModel else {
|
||||
return
|
||||
@ -66,15 +58,16 @@ public class StandardHeaderView: ViewConstrainingView, ModelMoleculeViewProtocol
|
||||
line?.setWithJSON(seperatorModel.toJSON(), delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
open override func reset() {
|
||||
super.reset()
|
||||
line?.style = .heavy
|
||||
topMarginPadding = PaddingDefaultVerticalSpacing
|
||||
bottomMarginPadding = PaddingDefaultVerticalSpacing
|
||||
line?.style = .heavy
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
if let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule), let height = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON)?.estimatedHeight?(forRow: moleculeJSON, delegateObject: delegateObject) {
|
||||
return height + PaddingDefaultVerticalSpacing + PaddingDefaultVerticalSpacing
|
||||
}
|
||||
|
||||
@ -22,15 +22,14 @@ import UIKit
|
||||
return
|
||||
}
|
||||
stack.spacing = 0
|
||||
stack.updateViewHorizontalDefaults = false
|
||||
addSubview(stack)
|
||||
pinView(toSuperView: stack)
|
||||
stack.addStackItem(StackItem(with: eyebrow), lastItem: false)
|
||||
stack.addStackItem(StackItem(with: headline), lastItem: false)
|
||||
stack.addStackItem(StackItem(with: body), lastItem: false)
|
||||
stack.addStackItem(StackItemModel(with: StackItemView(andContain: eyebrow)), lastItem: false)
|
||||
stack.addStackItem(StackItemModel(with: StackItemView(andContain: headline)), lastItem: false)
|
||||
stack.addStackItem(StackItemModel(with: StackItemView(andContain: body)), lastItem: false)
|
||||
|
||||
// To visually take into account the extra padding in the intrinsic content of a button.
|
||||
let stackItem = StackItem(with: link)
|
||||
let stackItem = StackItemModel(with: StackItemView(andContain: link))
|
||||
stackItem.spacing = -6
|
||||
stack.addStackItem(stackItem, lastItem: true)
|
||||
}
|
||||
@ -58,7 +57,6 @@ import UIKit
|
||||
super.reset()
|
||||
stack.reset()
|
||||
stack.spacing = 0
|
||||
stack.updateViewHorizontalDefaults = false
|
||||
eyebrow.styleB3(true)
|
||||
headline.styleB1(true)
|
||||
body.styleB2(true)
|
||||
|
||||
@ -8,49 +8,14 @@
|
||||
|
||||
import UIKit
|
||||
|
||||
public class StackItem {
|
||||
var view: UIView
|
||||
var spacing: CGFloat?
|
||||
var percentage: Int?
|
||||
var verticalAlignment: UIStackView.Alignment?
|
||||
var horizontalAlignment: UIStackView.Alignment?
|
||||
var gone = false
|
||||
|
||||
init(with view: UIView) {
|
||||
self.view = view
|
||||
}
|
||||
|
||||
init(with view: UIView, stackItemModel: MoleculeStackItemModel?) {
|
||||
self.view = view
|
||||
update(with: stackItemModel)
|
||||
}
|
||||
|
||||
func update(with stackItemModel: MoleculeStackItemModel?) {
|
||||
gone = stackItemModel?.gone ?? false
|
||||
spacing = stackItemModel?.spacing
|
||||
percentage = stackItemModel?.percentage
|
||||
|
||||
if let alignment = stackItemModel?.verticalAlignment {
|
||||
verticalAlignment = ViewConstrainingView.getAlignmentFor(alignment, defaultAlignment: .fill)
|
||||
} else {
|
||||
verticalAlignment = nil
|
||||
}
|
||||
if let alignment = stackItemModel?.horizontalAlignment {
|
||||
horizontalAlignment = ViewConstrainingView.getAlignmentFor(alignment, defaultAlignment: .fill)
|
||||
} else {
|
||||
horizontalAlignment = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol {
|
||||
open class MoleculeStackView: Container {
|
||||
var contentView: UIView = MVMCoreUICommonViewsUtility.commonView()
|
||||
var stackItems: [StackItem] = []
|
||||
var stackItems: [StackItemModel] = []
|
||||
var useStackSpacingBeforeFirstItem = false
|
||||
var moleculeStackModel: MoleculeStackModel?
|
||||
|
||||
private var moleculesShouldSetHorizontalMargins = false
|
||||
private var moleculesShouldSetVerticalMargins = false
|
||||
var moleculesShouldSetHorizontalMargins = false
|
||||
var moleculesShouldSetVerticalMargins = false
|
||||
|
||||
/// For setting the direction of the stack
|
||||
var axis: NSLayoutConstraint.Axis = .vertical {
|
||||
@ -99,6 +64,10 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol
|
||||
}
|
||||
|
||||
// MARK: - Inits
|
||||
public override init() {
|
||||
super.init()
|
||||
}
|
||||
|
||||
public override init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
}
|
||||
@ -119,19 +88,20 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol
|
||||
return
|
||||
}
|
||||
MVMCoreUIUtility.setMarginsFor(contentView, leading: 0, top: 0, trailing: 0, bottom: 0)
|
||||
updateViewHorizontalDefaults = true
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
backgroundColor = .clear
|
||||
addSubview(contentView)
|
||||
pinView(toSuperView: contentView)
|
||||
containerHelper.constrainView(contentView)
|
||||
contentView.setContentHuggingPriority(.defaultHigh, for: .vertical)
|
||||
contentView.setContentHuggingPriority(.defaultHigh, for: .horizontal)
|
||||
}
|
||||
|
||||
public override func updateView(_ size: CGFloat) {
|
||||
super.updateView(size)
|
||||
directionalLayoutMargins.leading = 0
|
||||
directionalLayoutMargins.trailing = 0
|
||||
for item in stackItems {
|
||||
(item.view as? MVMCoreViewProtocol)?.updateView(size)
|
||||
item.view.updateView(size)
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,16 +109,13 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol
|
||||
public override func reset() {
|
||||
super.reset()
|
||||
backgroundColor = .clear
|
||||
updateViewHorizontalDefaults = true
|
||||
for item in stackItems {
|
||||
if let view = item.view as? MVMCoreUIMoleculeViewProtocol {
|
||||
view.reset?()
|
||||
}
|
||||
item.view.reset()
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: Model, Change to model
|
||||
public func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
||||
public override func setWithModel(_ model: MoleculeProtocol?, _ delegateObject: MVMCoreUIDelegateObject?, _ additionalData: [String : AnyHashable]?) {
|
||||
guard let model = model as? MoleculeStackModel else {
|
||||
return
|
||||
}
|
||||
@ -157,11 +124,11 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol
|
||||
|
||||
#warning("This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.")
|
||||
//TODO: This below call should be repaced with super.setWithModel once we get rid of ViewConstrainingView.
|
||||
setUpWithModel(model, delegateObject, additionalData)
|
||||
//setUpWithModel(model, delegateObject, additionalData)
|
||||
removeAllItemViews()
|
||||
|
||||
// If the items in the stack are the same, just update previous items instead of re-allocating.
|
||||
var items: [StackItem]?
|
||||
var items: [StackItemModel]?
|
||||
|
||||
if let previousModel = previousModel {
|
||||
let previoudReuseName = MoleculeStackView.name(forReuse: previousModel, delegateObject: delegateObject)
|
||||
@ -185,22 +152,25 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol
|
||||
if let moleculeModel = stackItemModel.molecule {
|
||||
var view: UIView?
|
||||
if let item = items?[index] {
|
||||
item.update(with: stackItemModel)
|
||||
item.update(with: stackItemModel)
|
||||
view = item.view
|
||||
(view as? ModelMoleculeViewProtocol)?.setWithModel(moleculeModel, delegateObject, nil)
|
||||
addStackItem(item, lastItem: index == molecules.count - 1)
|
||||
} else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(moleculeModel, delegateObject, true) {
|
||||
} else if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(moleculeModel, delegateObject, true) as? StackItemView {
|
||||
view = moleculeView
|
||||
addStackItem(StackItem(with: moleculeView, stackItemModel: stackItemModel), lastItem: index == molecules.count - 1)
|
||||
addStackItem(StackItemModel(with: moleculeView, stackItemModel: stackItemModel), lastItem: index == molecules.count - 1)
|
||||
}
|
||||
(view as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(moleculesShouldSetHorizontalMargins)
|
||||
(view as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(moleculesShouldSetVerticalMargins)
|
||||
}
|
||||
|
||||
stackItemModel.useHorizontalMargins = moleculesShouldSetHorizontalMargins
|
||||
stackItemModel.useVerticalMargins = moleculesShouldSetVerticalMargins
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||
public class func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? {
|
||||
// This will aggregate names of molecules to make an id.
|
||||
guard let molecules = molecule?.optionalArrayForKey(KeyMolecules) else {
|
||||
return "stack<>"
|
||||
@ -215,7 +185,7 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol
|
||||
return name
|
||||
}
|
||||
|
||||
public override class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
public class func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
|
||||
guard let items = json?.optionalArrayForKey(KeyMolecules) else {
|
||||
return 0
|
||||
}
|
||||
@ -237,7 +207,7 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol
|
||||
return estimatedHeight
|
||||
}
|
||||
|
||||
public override class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
||||
public class func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
|
||||
guard let items = json?.optionalArrayForKey(KeyMolecules) else {
|
||||
return nil
|
||||
}
|
||||
@ -253,11 +223,11 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol
|
||||
// MARK: - Adding to stack
|
||||
/// Adds the view to the stack.
|
||||
func addView(_ view: UIView, lastItem: Bool) {
|
||||
addStackItem(StackItem(with: view), lastItem: lastItem)
|
||||
addStackItem(StackItemModel(with: StackItemView(andContain: view)), lastItem: lastItem)
|
||||
}
|
||||
|
||||
/// Adds the stack item to the stack.
|
||||
func addStackItem(_ stackItem: StackItem, lastItem: Bool) {
|
||||
func addStackItem(_ stackItem: StackItemModel, lastItem: Bool) {
|
||||
guard !stackItem.gone else {
|
||||
stackItems.append(stackItem)
|
||||
return
|
||||
@ -311,10 +281,10 @@ public class MoleculeStackView: ViewConstrainingView, ModelMoleculeViewProtocol
|
||||
stackItems.append(stackItem)
|
||||
}
|
||||
|
||||
func setWithStackItems(_ items: [StackItem]) {
|
||||
func setWithStackItems(_ items: [StackItemModel]) {
|
||||
removeAllItemViews()
|
||||
self.stackItems.removeAll()
|
||||
var previousPresentItem: StackItem? = nil
|
||||
stackItems.removeAll()
|
||||
var previousPresentItem: StackItemModel? = nil
|
||||
for item in items {
|
||||
if !item.gone {
|
||||
previousPresentItem = item
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
mapping = [@{
|
||||
@"label": Label.class,
|
||||
@"line": Line.class,
|
||||
@"button": ButtonView.class,
|
||||
@"button": PrimaryButton.class,
|
||||
@"textButton": MFTextButton.class,
|
||||
@"header": StandardHeaderView.class,
|
||||
@"moleculeStack": MoleculeStackView.class,
|
||||
|
||||
@ -16,7 +16,13 @@
|
||||
- (BOOL)needsToBeConstrained;
|
||||
|
||||
/// The alignment if constrained.
|
||||
- (UIStackViewAlignment)alignment;
|
||||
- (UIStackViewAlignment)alignment __deprecated;
|
||||
|
||||
/// The alignment if constrained.
|
||||
- (UIStackViewAlignment)horizontalAlignment;
|
||||
|
||||
/// The alignment if constrained.
|
||||
- (UIStackViewAlignment)verticalAlignment;
|
||||
|
||||
/// Can be used to override any standard constraints that may be added.
|
||||
- (BOOL)useStandardConstraints;
|
||||
|
||||
@ -61,6 +61,7 @@ open class MoleculeStackTemplate: ThreeLayerViewController, TemplateProtocol {
|
||||
|
||||
let stack = MoleculeStackView(frame: .zero)
|
||||
stack.useStackSpacingBeforeFirstItem = true
|
||||
stack.moleculesShouldSetHorizontalMargins = true
|
||||
stack.setWithModel(moleculeStackModel, delegateObject() as? MVMCoreUIDelegateObject, nil)
|
||||
return stack
|
||||
}
|
||||
|
||||
@ -77,3 +77,7 @@ typedef NS_ENUM(NSInteger, CoreUIErrorCode) {
|
||||
ErrorCodeModuleMolecule = 100,
|
||||
ErrorCodeListMolecule = 101
|
||||
};
|
||||
|
||||
#pragma mark - Apple Design Guidelines
|
||||
|
||||
extern CGFloat const MinimumTappableArea;
|
||||
|
||||
@ -69,3 +69,7 @@ BOOL DisableAnimations = NO;
|
||||
// Hand Scroll Key
|
||||
NSString * const KeyHandScrollAnimation = @"handScrollAnimation";
|
||||
NSString * const KeyHandScroll = @"hand_scroll";
|
||||
|
||||
#pragma mark - Apple Design Guidelines
|
||||
|
||||
CGFloat const MinimumTappableArea = 44.0f;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user