ModuleMolecule is now a self contained view.

Fixed priority defect in view constraining view.
Change the way names are set for reuse
improve current margin logic
This commit is contained in:
Pfeil, Scott Robert 2019-06-26 12:01:47 -04:00
parent ab33ceebde
commit 0db0f91b3b
12 changed files with 260 additions and 199 deletions

View File

@ -39,7 +39,6 @@
D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */; }; D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */; };
D296E13C229598BF0051EBE7 /* MoleculeListCellProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E13B2295969C0051EBE7 /* MoleculeListCellProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D296E13C229598BF0051EBE7 /* MoleculeListCellProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E13B2295969C0051EBE7 /* MoleculeListCellProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
D296E1412295EBBA0051EBE7 /* MoleculeDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D296E1412295EBBA0051EBE7 /* MoleculeDelegateProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
D296E143229729C30051EBE7 /* MoleculeMappingObject+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = D296E142229729C30051EBE7 /* MoleculeMappingObject+Extension.swift */; };
D296E14722A5984C0051EBE7 /* MVMCoreUIViewConstrainingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D296E14722A5984C0051EBE7 /* MVMCoreUIViewConstrainingProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */; }; D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */; };
D29770C921F7C4AE00B2F0D0 /* TopLabelsView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29770C921F7C4AE00B2F0D0 /* TopLabelsView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -49,6 +48,7 @@
D29770F521F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770F121F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m */; }; D29770F521F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770F121F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m */; };
D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770FA21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m */; }; D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770FA21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m */; };
D29770FD21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770FB21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29770FD21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770FB21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h */; settings = {ATTRIBUTES = (Public, ); }; };
D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */ = {isa = PBXBuildFile; fileRef = D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */; };
D29DF0D121E404D4003B2FB9 /* MVMCoreUI.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF0CF21E404D4003B2FB9 /* MVMCoreUI.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF0D121E404D4003B2FB9 /* MVMCoreUI.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF0CF21E404D4003B2FB9 /* MVMCoreUI.h */; settings = {ATTRIBUTES = (Public, ); }; };
D29DF0E621E4F3C7003B2FB9 /* MVMCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D29DF0E521E4F3C7003B2FB9 /* MVMCore.framework */; }; D29DF0E621E4F3C7003B2FB9 /* MVMCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D29DF0E521E4F3C7003B2FB9 /* MVMCore.framework */; };
D29DF11521E6805F003B2FB9 /* UIColor+MFConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF11121E6805F003B2FB9 /* UIColor+MFConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF11521E6805F003B2FB9 /* UIColor+MFConvenience.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF11121E6805F003B2FB9 /* UIColor+MFConvenience.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -207,7 +207,6 @@
D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIObject.m; sourceTree = "<group>"; }; D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIObject.m; sourceTree = "<group>"; };
D296E13B2295969C0051EBE7 /* MoleculeListCellProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MoleculeListCellProtocol.h; sourceTree = "<group>"; }; D296E13B2295969C0051EBE7 /* MoleculeListCellProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MoleculeListCellProtocol.h; sourceTree = "<group>"; };
D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MoleculeDelegateProtocol.h; sourceTree = "<group>"; }; D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MoleculeDelegateProtocol.h; sourceTree = "<group>"; };
D296E142229729C30051EBE7 /* MoleculeMappingObject+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MoleculeMappingObject+Extension.swift"; sourceTree = "<group>"; };
D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewConstrainingProtocol.h; sourceTree = "<group>"; }; D296E14622A597490051EBE7 /* MVMCoreUIViewConstrainingProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewConstrainingProtocol.h; sourceTree = "<group>"; };
D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsView.m; sourceTree = "<group>"; }; D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsView.m; sourceTree = "<group>"; };
D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TopLabelsView.h; sourceTree = "<group>"; }; D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TopLabelsView.h; sourceTree = "<group>"; };
@ -217,6 +216,7 @@
D29770F121F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsAndBottomButtonsViewController.m; sourceTree = "<group>"; }; D29770F121F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsAndBottomButtonsViewController.m; sourceTree = "<group>"; };
D29770FA21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUITextFieldView.m; sourceTree = "<group>"; }; D29770FA21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUITextFieldView.m; sourceTree = "<group>"; };
D29770FB21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUITextFieldView.h; sourceTree = "<group>"; }; D29770FB21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUITextFieldView.h; sourceTree = "<group>"; };
D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ModuleMolecule.swift; sourceTree = "<group>"; };
D29DF0CC21E404D4003B2FB9 /* MVMCoreUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MVMCoreUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D29DF0CC21E404D4003B2FB9 /* MVMCoreUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MVMCoreUI.framework; sourceTree = BUILT_PRODUCTS_DIR; };
D29DF0CF21E404D4003B2FB9 /* MVMCoreUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUI.h; sourceTree = "<group>"; }; D29DF0CF21E404D4003B2FB9 /* MVMCoreUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUI.h; sourceTree = "<group>"; };
D29DF0D021E404D4003B2FB9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; }; D29DF0D021E404D4003B2FB9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
@ -471,6 +471,7 @@
D2E1FADC2268B25E00AEFD8C /* MoleculeTableViewCell.swift */, D2E1FADC2268B25E00AEFD8C /* MoleculeTableViewCell.swift */,
B8200E142280C4CF007245F4 /* ProgressBar.swift */, B8200E142280C4CF007245F4 /* ProgressBar.swift */,
B8200E182281DC1A007245F4 /* ProgressBarWithLabel.swift */, B8200E182281DC1A007245F4 /* ProgressBarWithLabel.swift */,
D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */,
); );
path = Molecules; path = Molecules;
sourceTree = "<group>"; sourceTree = "<group>";
@ -679,7 +680,6 @@
D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */, D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */,
D2A514562211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.h */, D2A514562211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.h */,
D2A514572211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m */, D2A514572211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m */,
D296E142229729C30051EBE7 /* MoleculeMappingObject+Extension.swift */,
); );
path = OtherHandlers; path = OtherHandlers;
sourceTree = "<group>"; sourceTree = "<group>";
@ -901,6 +901,7 @@
D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */, D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */,
DBC4391822442197001AB423 /* CaretView.swift in Sources */, DBC4391822442197001AB423 /* CaretView.swift in Sources */,
D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */, D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */,
D29B771022C281F400D6ACE0 /* ModuleMolecule.swift in Sources */,
DBC4391922442197001AB423 /* DashLine.swift in Sources */, DBC4391922442197001AB423 /* DashLine.swift in Sources */,
D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */, D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */,
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */, D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */,
@ -944,7 +945,6 @@
D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */, D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */,
D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationController.m in Sources */, D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationController.m in Sources */,
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
D296E143229729C30051EBE7 /* MoleculeMappingObject+Extension.swift in Sources */,
01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */, 01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */,
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */,
D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */, D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */,

View File

@ -48,11 +48,21 @@
#pragma mark - Constraining #pragma mark - Constraining
- (void)pinViewToSuperView:(nonnull UIView *)view { - (void)pinViewToSuperView:(nonnull UIView *)view {
NSDictionary *dictionary = [NSLayoutConstraint constraintPinSubviewToSuperview:view]; NSLayoutConstraint *constraint = [view.leftAnchor constraintEqualToAnchor:view.superview.leftAnchor];
self.leftPin = dictionary[ConstraintLeading]; constraint.active = YES;
self.topPin = dictionary[ConstraintTop]; self.leftPin = constraint;
self.bottomPin = dictionary[ConstraintBot];
self.rightPin = dictionary[ConstraintTrailing]; constraint = [view.topAnchor constraintEqualToAnchor:view.superview.topAnchor];
constraint.active = YES;
self.topPin = constraint;
constraint = [view.superview.rightAnchor constraintEqualToAnchor:view.rightAnchor];
constraint.active = YES;
self.rightPin = constraint;
constraint = [view.superview.bottomAnchor constraintEqualToAnchor:view.bottomAnchor];
constraint.active = YES;
self.bottomPin = constraint;
self.alignCenterPin = [view.centerXAnchor constraintEqualToAnchor:view.superview.centerXAnchor]; self.alignCenterPin = [view.centerXAnchor constraintEqualToAnchor:view.superview.centerXAnchor];
self.alignCenterLeftPin = [view.leftAnchor constraintGreaterThanOrEqualToAnchor:view.superview.leftAnchor]; self.alignCenterLeftPin = [view.leftAnchor constraintGreaterThanOrEqualToAnchor:view.superview.leftAnchor];

View File

@ -64,7 +64,7 @@ import UIKit
primaryButton?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) primaryButton?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
} }
public override static func estimatedHeight(forRow json: [AnyHashable : Any]?) -> CGFloat { public override static func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
return 42 return 42
} }

View File

@ -9,6 +9,7 @@
#import <UIKit/UIKit.h> #import <UIKit/UIKit.h>
@import MVMCore.MVMCoreViewProtocol; @import MVMCore.MVMCoreViewProtocol;
@class MVMCoreUIDelegateObject; @class MVMCoreUIDelegateObject;
@class MVMCoreErrorObject;
@protocol MVMCoreUIMoleculeViewProtocol <NSObject, MVMCoreViewProtocol> @protocol MVMCoreUIMoleculeViewProtocol <NSObject, MVMCoreViewProtocol>
@ -25,11 +26,14 @@
/// For the molecule list to load more efficiently. /// For the molecule list to load more efficiently.
+ (CGFloat)estimatedHeightForRow:(nullable NSDictionary *)json; + (CGFloat)estimatedHeightForRow:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject;
/// Allows the molecule to set its name for reuse. Default could be moleculeName. /// Allows the molecule to set its name for reuse. Default could be moleculeName.
+ (nullable NSString *)nameForReuse:(nullable NSDictionary *)molecule delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject; + (nullable NSString *)nameForReuse:(nullable NSDictionary *)molecule delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject;
/// Can return the required modules
+ (nullable NSArray <NSString *>*)requiredModules:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject error:(MVMCoreErrorObject *_Nullable *_Nullable)error;
@end @end

View File

@ -0,0 +1,98 @@
//
// ModuleMolecule.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 6/25/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import UIKit
open class ModuleMolecule: ViewConstrainingView {
open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)?
open override func updateView(_ size: CGFloat) {
super.updateView(size)
molecule?.updateView(size)
}
// MARK: - MVMCoreUIMoleculeViewProtocol
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
guard let moduleName = json?.optionalStringForKey("moduleName"), let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
// Critical error
return
}
if molecule == nil {
if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: module, delegateObject: delegateObject, constrainIfNeeded: true) {
addSubview(moleculeView)
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: false).values))
molecule = moleculeView
}
} else {
molecule?.setWithJSON(module, delegateObject: delegateObject, additionalData: additionalData)
}
}
open override func setAsMolecule() {
super.setAsMolecule()
updateViewHorizontalDefaults = false
molecule?.setAsMolecule?()
}
open override func reset() {
super.reset()
molecule?.reset?()
}
public override static func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
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) ?? 80
}
public override static func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? {
guard let moduleName = molecule?.optionalStringForKey("moduleName"), let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
// Critical error
return "moduleMolecule<>"
}
return "moduleMolecule<" + (MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: module)?.name?(forReuse: module, delegateObject: delegateObject) ?? module.stringForkey(KeyMoleculeName)) + ">"
}
public override static func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
guard let moduleName = json?.optionalStringForKey("moduleName"), let _ = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
if let errorObject = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), code: CoreUIErrorCode.ErrorCodeModuleMolecule.rawValue, domain: ErrorDomainNative, location: String(describing: self)) {
error?.pointee = errorObject
MVMCoreUILoggingHandler.shared()?.addError(toLog: errorObject)
}
return nil
}
return [moduleName]
}
// MARK: - MVMCoreUIViewConstrainingProtocol
open override func useStandardConstraints() -> Bool {
return (molecule as? MVMCoreUIViewConstrainingProtocol)?.useStandardConstraints?() ?? true
}
open override func alignHorizontal(_ alignment: UIStackView.Alignment) {
(molecule as? MVMCoreUIViewConstrainingProtocol)?.alignHorizontal?(alignment)
}
open override func alignVertical(_ alignment: UIStackView.Alignment) {
(molecule as? MVMCoreUIViewConstrainingProtocol)?.alignVertical?(alignment)
}
open override func shouldSetHorizontalMargins(_ shouldSet: Bool) {
(molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(shouldSet)
}
open override func shouldSetVerticalMargins(_ shouldSet: Bool) {
(molecule as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(shouldSet)
}
}

View File

@ -47,6 +47,7 @@ public class MoleculeStackView: ViewConstrainingView {
/// For setting the direction of the stack /// For setting the direction of the stack
var axis: NSLayoutConstraint.Axis = .vertical { var axis: NSLayoutConstraint.Axis = .vertical {
didSet { didSet {
moleculesShouldSetHorizontalMargins = (moleculesShouldSetHorizontalMargins && axis == .vertical)
if axis != oldValue { if axis != oldValue {
restack() restack()
} }
@ -136,15 +137,20 @@ public class MoleculeStackView: ViewConstrainingView {
} }
} }
// If this item is in another container, do have the child molecules not use alignment.
public override func shouldSetHorizontalMargins(_ shouldSet: Bool) { public override func shouldSetHorizontalMargins(_ shouldSet: Bool) {
super.shouldSetHorizontalMargins(shouldSet) super.shouldSetHorizontalMargins(shouldSet)
moleculesShouldSetHorizontalMargins = false moleculesShouldSetHorizontalMargins = (shouldSet && axis == .vertical)
for item in items {
(item.view as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(moleculesShouldSetHorizontalMargins)
}
} }
public override func shouldSetVerticalMargins(_ shouldSet: Bool) { public override func shouldSetVerticalMargins(_ shouldSet: Bool) {
super.shouldSetVerticalMargins(shouldSet) super.shouldSetVerticalMargins(shouldSet)
moleculesShouldSetVerticalMargins = false moleculesShouldSetVerticalMargins = false
for item in items {
(item.view as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(moleculesShouldSetVerticalMargins)
}
} }
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
@ -187,32 +193,51 @@ public class MoleculeStackView: ViewConstrainingView {
if let item = items?[index] { if let item = items?[index] {
item.update(with: moleculeJSON) item.update(with: moleculeJSON)
view = item.view view = item.view
(view as? MVMCoreUIMoleculeViewProtocol)?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: nil)
addStackItem(item, lastItem: index == molecules.count - 1) addStackItem(item, lastItem: index == molecules.count - 1)
} else if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: true) { } else if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: true) {
view = molecule view = molecule
addStackItem(StackItem(with: molecule, json: map), lastItem: index == molecules.count - 1) addStackItem(StackItem(with: molecule, json: map), lastItem: index == molecules.count - 1)
} }
(view as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(moleculesShouldSetHorizontalMargins && axis == .vertical) (view as? MVMCoreUIViewConstrainingProtocol)?.shouldSetHorizontalMargins?(moleculesShouldSetHorizontalMargins)
(view as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(moleculesShouldSetVerticalMargins) (view as? MVMCoreUIViewConstrainingProtocol)?.shouldSetVerticalMargins?(moleculesShouldSetVerticalMargins)
(view as? MVMCoreUIMoleculeViewProtocol)?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: nil)
} }
} }
} }
public override static func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { public override static func name(forReuse molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? {
// This will aggregate names of molecules to make an id. // This will aggregate names of molecules to make an id.
var name = ""
guard let molecules = molecule?.optionalArrayForKey(KeyMolecules) else { guard let molecules = molecule?.optionalArrayForKey(KeyMolecules) else {
return name return "stack<>"
} }
var name = "stack<"
for case let item as [AnyHashable: AnyHashable] in molecules { for case let item as [AnyHashable: AnyHashable] in molecules {
if let moleculeName = item.stringOptionalWithChainOfKeysOrIndexes([KeyMolecule, KeyMoleculeName]) { if let molecule = item.optionalDictionaryForKey(KeyMolecule), let moleculeName = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: molecule)?.name?(forReuse: molecule, delegateObject: delegateObject) ?? molecule.optionalStringForKey(KeyMoleculeName) {
name.append(moleculeName) name.append(moleculeName + ",")
} }
} }
name.append(">")
return name return name
} }
public override static func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
// if horizontal, max, if vertical, append.
return 100
}
public override static func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
guard let items = json?.optionalArrayForKey(KeyMolecules) else {
return nil
}
var modules: [String] = []
for case let item as [AnyHashable: AnyHashable] in items {
if let molecule = item.optionalDictionaryForKey(KeyMolecule), let modulesForMolecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: molecule)?.requiredModules?(molecule, delegateObject: delegateObject, error: error) {
modules += modulesForMolecule
}
}
return modules.count > 0 ? modules : nil
}
// MARK: - Adding to stack // MARK: - Adding to stack
/// Adds the view to the stack. /// Adds the view to the stack.
func addView(_ view: UIView, lastItem: Bool) { func addView(_ view: UIView, lastItem: Bool) {

View File

@ -98,13 +98,14 @@ import UIKit
} }
molecule = moleculeView molecule = moleculeView
} }
} else {
molecule?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData)
} }
if let castView = molecule as? MVMCoreUIViewConstrainingProtocol { if let castView = molecule as? MVMCoreUIViewConstrainingProtocol {
let standardConstraints = castView.useStandardConstraints?() ?? true let standardConstraints = castView.useStandardConstraints?() ?? true
castView.shouldSetHorizontalMargins?(!standardConstraints) castView.shouldSetHorizontalMargins?(!standardConstraints)
castView.shouldSetVerticalMargins?(!standardConstraints) castView.shouldSetVerticalMargins?(!standardConstraints)
} }
molecule?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData)
backgroundColor = molecule?.backgroundColor backgroundColor = molecule?.backgroundColor
@ -126,25 +127,26 @@ import UIKit
molecule?.reset?() molecule?.reset?()
} }
public static func estimatedHeight(forRow json: [AnyHashable: Any]?) -> CGFloat { public static func estimatedHeight(forRow json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat {
guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule), guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule), let height = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON)?.estimatedHeight?(forRow: moleculeJSON, delegateObject: delegateObject) else {
let theClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON, delegateObject: nil),
let estimatedHeightFor = theClass.estimatedHeight else {
return 80 return 80
} }
return estimatedHeightFor(moleculeJSON) return height
} }
public static func name(forReuse molecule: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { public static func name(forReuse molecule: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? {
if let molecule = molecule?.optionalDictionaryForKey(KeyMolecule), guard let molecule = molecule?.optionalDictionaryForKey(KeyMolecule) else {
let moleculeName = molecule.optionalStringForKey(KeyMoleculeName), return nil
let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping[moleculeName] as? AnyClass,
let castClass = moleculeClass as? MVMCoreUIMoleculeViewProtocol.Type,
let nameFunc = castClass.name {
return nameFunc(molecule, delegateObject)
} else {
return molecule?.optionalDictionaryForKey(KeyMolecule)?.optionalStringForKey(KeyMoleculeName)
} }
return MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: molecule)?.name?(forReuse: molecule, delegateObject: delegateObject) ?? molecule.optionalStringForKey(KeyMoleculeName)
}
public static func requiredModules(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject?>?) -> [String]? {
guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule),
let theClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON) else {
return nil
}
return theClass.requiredModules?(moleculeJSON, delegateObject: delegateObject, error: error)
} }
// MARK: - Arrow // MARK: - Arrow

View File

@ -21,22 +21,19 @@
+ (nullable instancetype)sharedMappingObject; + (nullable instancetype)sharedMappingObject;
/// Returns the molecule class. /// Returns the molecule class.
- (nullable Class)getMoleculeClassWithJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject; - (nullable Class)getMoleculeClassWithJSON:(nonnull NSDictionary *)json;
#pragma mark - Molecule Creation #pragma mark - Molecule Creation
/// Creates the molecule for the given name. /// Creates the molecule for the molecule json.
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForName:(nonnull NSString *)name;
/// Creates the molecule for the molecule json. Takes into account moduleMolecule as well.
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject; - (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject;
/// Creates the molecule for the molecule json. Takes into account moduleMolecule as well. Also checks if the molecule needs to be constrained for a stack/list style situation. /// Creates the molecule for the molecule json. Also checks if the molecule needs to be constrained for a stack/list style situation.
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject constrainIfNeeded:(BOOL)constrainIfNeeded; - (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject constrainIfNeeded:(BOOL)constrainIfNeeded;
#pragma mark - ModuleMolecule Helpers #pragma mark - Convenience
/// If the molecule is a module molecule, will get the map for the molecule to load from a module. Otherwise nil. + (nullable NSArray <NSString *>*)getRequiredModulesForJSON:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject error:(MVMCoreErrorObject *_Nullable *_Nullable)error;
+ (nullable NSDictionary *)getMoleculeMapForModuleMolecule:(nullable NSDictionary *)moduleMolecule delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject error:(MVMCoreErrorObject *_Nullable *_Nullable)error; + (void)addRequiredModulesForJSON:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject moduleList:(nullable NSMutableArray <NSDictionary *>*)moduleList errorList:(nullable NSMutableArray <MVMCoreErrorObject *>*)errorList;
@end @end

View File

@ -10,6 +10,7 @@
@import MVMCore.MVMCoreActionUtility; @import MVMCore.MVMCoreActionUtility;
@import MVMCore.NSDictionary_MFConvenience; @import MVMCore.NSDictionary_MFConvenience;
@import MVMCore.MVMCoreLoadObject; @import MVMCore.MVMCoreLoadObject;
@import MVMCore.MVMCoreErrorObject;
#import "MVMCoreUIObject.h" #import "MVMCoreUIObject.h"
#import <MVMCoreUI/MVMCoreUI-Swift.h> #import <MVMCoreUI/MVMCoreUI-Swift.h>
#import "MFTextField.h" #import "MFTextField.h"
@ -44,7 +45,8 @@
@"switchLineItem": SwitchLineItem.class, @"switchLineItem": SwitchLineItem.class,
@"switch": Switch.class, @"switch": Switch.class,
@"image": MFLoadImageView.class, @"image": MFLoadImageView.class,
@"leftRightLabelView": LeftRightLabelView.class @"leftRightLabelView": LeftRightLabelView.class,
@"moduleMolecule": ModuleMolecule.class
} mutableCopy]; } mutableCopy];
}); });
return mapping; return mapping;
@ -55,9 +57,8 @@
return [MVMCoreActionUtility initializerClassCheck:[MVMCoreUIObject sharedInstance].moleculeMap classToVerify:self]; return [MVMCoreActionUtility initializerClassCheck:[MVMCoreUIObject sharedInstance].moleculeMap classToVerify:self];
} }
- (nullable Class)getMoleculeClassWithJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { - (nullable Class)getMoleculeClassWithJSON:(nonnull NSDictionary *)json {
NSDictionary *moleculeJSON = [MVMCoreUIMoleculeMappingObject getMoleculeMapForModuleMolecule:json delegateObject:delegateObject error:nil] ?: json; NSString *moleculeName = [json string:KeyMoleculeName];
NSString *moleculeName = [moleculeJSON string:KeyMoleculeName];
if (moleculeName) { if (moleculeName) {
return [self.moleculeMapping objectForKey:moleculeName]; return [self.moleculeMapping objectForKey:moleculeName];
} }
@ -83,12 +84,12 @@
} }
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject constrainIfNeeded:(BOOL)constrainIfNeeded { - (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject constrainIfNeeded:(BOOL)constrainIfNeeded {
NSDictionary *moleculeJSON = [MVMCoreUIMoleculeMappingObject getMoleculeMapForModuleMolecule:json delegateObject:delegateObject error:nil] ?: json; NSString *moleculeName = [json string:KeyMoleculeName];
NSString *moleculeName = [moleculeJSON string:KeyMoleculeName];
if (!moleculeName) { if (!moleculeName) {
return nil; return nil;
} }
UIView <MVMCoreUIMoleculeViewProtocol>*molecule = [self createMoleculeForName:moleculeName]; UIView <MVMCoreUIMoleculeViewProtocol>*molecule = [self createMoleculeForName:moleculeName];
[molecule setWithJSON:json delegateObject:delegateObject additionalData:nil];
// Check if we need to constrain this view. // Check if we need to constrain this view.
UIView <MVMCoreUIViewConstrainingProtocol> *castMolecule = [molecule conformsToProtocol:@protocol(MVMCoreUIViewConstrainingProtocol)] ? (UIView <MVMCoreUIViewConstrainingProtocol> *)molecule : nil; UIView <MVMCoreUIViewConstrainingProtocol> *castMolecule = [molecule conformsToProtocol:@protocol(MVMCoreUIViewConstrainingProtocol)] ? (UIView <MVMCoreUIViewConstrainingProtocol> *)molecule : nil;
@ -98,20 +99,26 @@
return molecule; return molecule;
} }
#pragma mark - ModuleMolecule Helpers #pragma mark - Convenience
+ (nullable NSDictionary *)getMoleculeMapForModuleMolecule:(nullable NSDictionary *)moduleMolecule delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject error:(MVMCoreErrorObject *_Nullable *_Nullable)error { + (nullable NSArray <NSString *>*)getRequiredModulesForJSON:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject error:(MVMCoreErrorObject *_Nullable *_Nullable)error {
NSString *moleculeName = [moduleMolecule string:KeyMoleculeName]; Class <MVMCoreUIMoleculeViewProtocol>theClass = [[MVMCoreUIMoleculeMappingObject sharedMappingObject] getMoleculeClassWithJSON:json];
if ([moleculeName isEqualToString:@"moduleMolecule"]) { if ([theClass respondsToSelector:@selector(requiredModules:delegateObject:error:)]) {
NSString *moduleName = [moduleMolecule string:@"moduleName"]; return [theClass requiredModules:json delegateObject:delegateObject error:error];
NSDictionary *module = moduleName ? [delegateObject.moleculeDelegate getModuleWithName:moduleName] : nil;
if (!module && error) {
*error = [[MVMCoreErrorObject alloc] initWithTitle:nil message:[MVMCoreGetterUtility hardcodedStringWithKey:HardcodedErrorUnableToProcess] code:ErrorCodeModuleMolecule domain:ErrorDomainNative location:NSStringFromClass(self)];
}
return module;
} else { } else {
return nil; return nil;
} }
} }
+ (void)addRequiredModulesForJSON:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject moduleList:(nullable NSMutableArray <NSDictionary *>*)moduleList errorList:(nullable NSMutableArray <MVMCoreErrorObject *>*)errorList {
MVMCoreErrorObject *error = nil;
NSArray *modules = [self getRequiredModulesForJSON:json delegateObject:delegateObject error:&error];
if (modules) {
[moduleList addObjectsFromArray:modules];
}
if (error) {
[errorList addObject:error];
}
}
@end @end

View File

@ -1,47 +0,0 @@
//
// MoleculeMappingObject+Extension.swift
// MVMCoreUI
//
// Created by Scott Pfeil on 5/23/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import Foundation
public extension MVMCoreUIMoleculeMappingObject {
/// Gets the molecule, and if it belonged to a moduleMolecule, the module name or error.
static func getMoleculeJSON(for map: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> (molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)? {
guard let map = map, let moleculeName = map.optionalStringForKey(KeyMoleculeName) else {
return nil
}
guard moleculeName == "moduleMolecule" else {
// Not a module molecule.
return (map, nil, nil)
}
guard let moduleName = map.optionalStringForKey("moduleName"),
let module = delegateObject?.moleculeDelegate?.getModuleWithName(moduleName) else {
guard let error = MVMCoreErrorObject(title: nil, message: MVMCoreGetterUtility.hardcodedString(withKey: HardcodedErrorUnableToProcess), code: CoreUIErrorCode.ErrorCodeModuleMolecule.rawValue, domain: ErrorDomainNative, location: String(describing: self)) else {
return nil
}
MVMCoreUILoggingHandler.shared()?.addError(toLog: error)
return (nil, nil, error)
}
return (module, moduleName, nil)
}
/// Gets the molecule, and if it belonged to a moduleMolecule adds the module name or error to the passed lists.
static func getMoleculeJSON(for map: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, moduleNames: inout [String]?, errors: inout [MVMCoreErrorObject]?) -> [AnyHashable: Any]? {
guard let molecule = getMoleculeJSON(for: map, delegateObject: delegateObject) else {
return nil
}
if let moduleName = molecule.moduleName {
moduleNames?.append(moduleName)
}
if let error = molecule.error {
errors?.append(error)
}
return molecule.molecule
}
}

View File

@ -9,7 +9,8 @@
import UIKit import UIKit
open class MoleculeListTemplate: ThreeLayerTableViewController { open class MoleculeListTemplate: ThreeLayerTableViewController {
var molecules: [(molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)]? var moleculesInfo: [(identifier: String, class: AnyClass, molecule: [AnyHashable: Any])]?
var modulesRequired: NSMutableArray?
open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool { open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
var shouldFinish = super.shouldFinishProcessingLoad(loadObject, error: error) var shouldFinish = super.shouldFinishProcessingLoad(loadObject, error: error)
@ -17,7 +18,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController {
return shouldFinish return shouldFinish
} }
if let firstError = setup()?.first { if let firstError = setup()?.firstObject as? MVMCoreErrorObject {
// Don't continue if there was an error loading needed modules. // Don't continue if there was an error loading needed modules.
error.pointee = firstError error.pointee = firstError
shouldFinish = false shouldFinish = false
@ -30,7 +31,6 @@ open class MoleculeListTemplate: ThreeLayerTableViewController {
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else { let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else {
return super.viewForTop() return super.viewForTop()
} }
molecule.setWithJSON(moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
return molecule return molecule
} }
@ -39,47 +39,43 @@ open class MoleculeListTemplate: ThreeLayerTableViewController {
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else { let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else {
return super.viewForBottom() return super.viewForBottom()
} }
molecule.setWithJSON(moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
return molecule return molecule
} }
open override func newDataBuildScreen() { open override func newDataBuildScreen() {
super.newDataBuildScreen() super.newDataBuildScreen()
_ = setupMoleculeList() _ = setup()
registerWithTable() registerWithTable()
} }
// MARK: - table // MARK: - table
open override func registerWithTable() { open override func registerWithTable() {
super.registerWithTable() super.registerWithTable()
guard let molecules = molecules else { guard let moleculesInfo = moleculesInfo else {
return return
} }
for molecule in molecules { for moleculeInfo in moleculesInfo {
if let moleculeInfo = getMoleculeInfo(with: molecule), let moleculeToRegister = moleculeInfo.name { print(moleculeInfo.identifier)
tableView?.register(moleculeInfo.class, forCellReuseIdentifier: moleculeToRegister) tableView?.register(moleculeInfo.class, forCellReuseIdentifier: moleculeInfo.identifier)
}
} }
} }
open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
guard let molecule = molecules?[indexPath.row], guard let moleculeInfo = moleculesInfo?[indexPath.row],
let moleculeInfo = getMoleculeInfo(with: molecule), let estimatedHeight = moleculeInfo.class.estimatedHeight?(forRow: moleculeInfo.molecule, delegateObject: delegateObject() as? MVMCoreUIDelegateObject) else {
let estimatedHeight = moleculeInfo.class.estimatedHeight else {
return 0 return 0
} }
return estimatedHeight(molecule.molecule) print("height :" + moleculeInfo.class.description() + " :" + estimatedHeight.description)
return estimatedHeight
} }
open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return molecules?.count ?? 0 return moleculesInfo?.count ?? 0
} }
open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let molecule = molecules?[indexPath.row], guard let moleculeInfo = moleculesInfo?[indexPath.row],
let moleculeInfo = getMoleculeInfo(with: molecule), let cell = tableView.dequeueReusableCell(withIdentifier: moleculeInfo.identifier) else {
let moleculeName = moleculeInfo.name,
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeName) else {
return UITableViewCell() return UITableViewCell()
} }
let delegate = delegateObject() as? MVMCoreUIDelegateObject let delegate = delegateObject() as? MVMCoreUIDelegateObject
@ -88,7 +84,7 @@ open class MoleculeListTemplate: ThreeLayerTableViewController {
} }
if let protocolCell = cell as? MVMCoreUIMoleculeViewProtocol { if let protocolCell = cell as? MVMCoreUIMoleculeViewProtocol {
protocolCell.reset?() protocolCell.reset?()
protocolCell.setWithJSON(molecule.molecule, delegateObject: delegate, additionalData: nil) protocolCell.setWithJSON(moleculeInfo.molecule, delegateObject: delegate, additionalData: nil)
protocolCell.updateView(tableView.bounds.width) protocolCell.updateView(tableView.bounds.width)
} }
return cell return cell
@ -110,78 +106,52 @@ open class MoleculeListTemplate: ThreeLayerTableViewController {
open override func modulesToListenFor() -> [Any]? { open override func modulesToListenFor() -> [Any]? {
// Get all of the molecules that need modules. // Get all of the molecules that need modules.
return modulesNeeded() return modulesRequired as? [Any]
} }
// MARK: - Module Molecule Handling // MARK: - Convenience
/// Returns the (name, class) of the molecule for the given map. /// Returns the (identifier, class) of the molecule for the given map.
func getMoleculeInfo(with molecule: (molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)) -> (name: String?, class: AnyClass)? { func getMoleculeInfo(with molecule: [AnyHashable: Any]?) -> (identifier: String, class: AnyClass, molecule: [AnyHashable: Any])? {
guard let map = molecule.molecule, let moleculeName = map.optionalStringForKey(KeyMoleculeName), let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping[moleculeName] as? AnyClass else { guard let molecule = molecule,
let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: molecule),
let moleculeName = moleculeClass.name?(forReuse: molecule, delegateObject: delegateObject() as? MVMCoreUIDelegateObject) ?? molecule.optionalStringForKey(KeyMoleculeName) else {
return nil return nil
} }
if let moleculeClass = moleculeClass as? MVMCoreUIMoleculeViewProtocol.Type, let moleculeNameFunc = moleculeClass.name { return (moleculeName, moleculeClass, molecule)
return (moleculeNameFunc(map, delegateObject() as? MVMCoreUIDelegateObject), moleculeClass)
} else {
return (moleculeName, moleculeClass)
}
} }
/// Sets up the molecule list and ensures no errors loading all content. /// Sets up the molecule list and ensures no errors loading all content.
func setupMoleculeList() -> [MVMCoreErrorObject]? { func getMoleculeInfoList() -> [(identifier: String, class: AnyClass, molecule: [AnyHashable: Any])]? {
var errors: [MVMCoreErrorObject] = [] var moleculeList: [(identifier: String, class: AnyClass, molecule: [AnyHashable: Any])] = []
let delegate = delegateObject() as? MVMCoreUIDelegateObject
var moleculeList: [(molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)] = []
if let molecules = loadObject?.pageJSON?.optionalArrayForKey(KeyMolecules) as? [[AnyHashable: Any]] { if let molecules = loadObject?.pageJSON?.optionalArrayForKey(KeyMolecules) as? [[AnyHashable: Any]] {
for molecule in molecules { for molecule in molecules {
if let object = MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: molecule, delegateObject: delegate) { if let info = getMoleculeInfo(with: molecule) {
if let error = object.error { moleculeList.append(info)
errors.append(error)
} else {
moleculeList.append(object)
}
} }
} }
} }
molecules = moleculeList return moleculeList.count > 0 ? moleculeList : nil
return errors.count > 0 ? errors : nil
} }
/// Sets up the header, footer, molecule list and ensures no errors loading all content. /// Sets up the header, footer, molecule list and ensures no errors loading all content.
func setup() -> [MVMCoreErrorObject]? { func setup() -> NSMutableArray? {
var errors: [MVMCoreErrorObject] = [] let modules: NSMutableArray = []
let errors: NSMutableArray = []
let delegate = delegateObject() as? MVMCoreUIDelegateObject let delegate = delegateObject() as? MVMCoreUIDelegateObject
MoleculeListTemplate.addToErrorList(with: MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate), errors: &errors) MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate, moduleList: modules, errorList: errors)
MoleculeListTemplate.addToErrorList(with: MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate), errors: &errors) MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate, moduleList: modules, errorList: errors)
if let newErrors = setupMoleculeList() {
errors.append(contentsOf: newErrors)
}
return errors.count > 0 ? errors : nil
}
static func addToErrorList(with moleculeObject: (molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)?, errors: inout [MVMCoreErrorObject]) { var moleculeList: [(identifier: String, class: AnyClass, molecule: [AnyHashable: Any])] = []
if let error = moleculeObject?.error { if let molecules = loadObject?.pageJSON?.optionalArrayForKey(KeyMolecules) as? [[AnyHashable: Any]] {
errors.append(error)
}
}
static func addToModuleList(with moleculeObject: (molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)?, moduleNames: inout [String]) {
if let moduleName = moleculeObject?.moduleName {
moduleNames.append(moduleName)
}
}
/// Gets a list of required modules
func modulesNeeded() -> [String]? {
var modules: [String] = []
let delegate = delegateObject() as? MVMCoreUIDelegateObject
MoleculeListTemplate.addToModuleList(with: MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate), moduleNames: &modules)
MoleculeListTemplate.addToModuleList(with: MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate), moduleNames: &modules)
if let molecules = molecules {
for molecule in molecules { for molecule in molecules {
MoleculeListTemplate.addToModuleList(with: molecule, moduleNames: &modules) if let info = getMoleculeInfo(with: molecule) {
moleculeList.append(info)
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: molecule, delegateObject: delegate, moduleList: modules, errorList: errors)
}
} }
} }
return (modules.count > 0 ? modules : nil) moleculesInfo = moleculeList
modulesRequired = modules
return errors.count > 0 ? errors : nil
} }
} }

View File

@ -9,10 +9,11 @@
import UIKit import UIKit
public class MoleculeStackTemplate: ThreeLayerViewController { public class MoleculeStackTemplate: ThreeLayerViewController {
var modulesRequired: NSMutableArray?
public override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool { public override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
var shouldFinish = super.shouldFinishProcessingLoad(loadObject, error: error) var shouldFinish = super.shouldFinishProcessingLoad(loadObject, error: error)
if shouldFinish, let firstError = modulesNeeded().errors?.first { if shouldFinish, let firstError = modulesNeeded().errors?.firstObject as? MVMCoreErrorObject {
// Don't continue if there was an error loading needed modules. // Don't continue if there was an error loading needed modules.
error.pointee = firstError error.pointee = firstError
shouldFinish = false shouldFinish = false
@ -28,7 +29,6 @@ public class MoleculeStackTemplate: ThreeLayerViewController {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else { guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else {
return nil return nil
} }
molecule.setWithJSON(moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
return molecule return molecule
} }
@ -46,7 +46,6 @@ public class MoleculeStackTemplate: ThreeLayerViewController {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else { guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else {
return nil return nil
} }
molecule.setWithJSON(moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
return molecule return molecule
} }
@ -60,22 +59,18 @@ public class MoleculeStackTemplate: ThreeLayerViewController {
public override func modulesToListenFor() -> [Any]? { public override func modulesToListenFor() -> [Any]? {
// Get all of the molecules that need modules. // Get all of the molecules that need modules.
return modulesNeeded().modules return modulesNeeded().modules as? [Any]
} }
// MARK: - Module Molecule Handling /// Gets the modules needed.
func modulesNeeded() -> (modules: [String]?, errors: [MVMCoreErrorObject]?) { func modulesNeeded() -> (modules: NSMutableArray?, errors: NSMutableArray?) {
var modules: [String]? = [] let modules: NSMutableArray = []
var errors: [MVMCoreErrorObject]? = [] let errors: NSMutableArray = []
let delegate = delegateObject() as? MVMCoreUIDelegateObject let delegate = delegateObject() as? MVMCoreUIDelegateObject
MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate, moduleList: modules, errorList: errors)
let _ = MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate, moduleNames: &modules, errors: &errors) MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate, moduleList: modules, errorList: errors)
let _ = MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate, moduleNames: &modules, errors: &errors) MVMCoreUIMoleculeMappingObject.addRequiredModules(forJSON: loadObject?.pageJSON?.optionalDictionaryForKey("moleculeStack"), delegateObject: delegate, moduleList: modules, errorList: errors)
if let molecules = loadObject?.pageJSON?.optionalArrayForChainOfKeysOrIndexes(["moleculeStack",KeyMolecules]) as? [[AnyHashable: Any]] { modulesRequired = modules
for molecule in molecules { return (modules.count > 0 ? modules : nil, errors.count > 0 ? errors : nil)
let _ = MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: molecule, delegateObject: delegate, moduleNames: &modules, errors: &errors)
}
}
return (modules?.count ?? 0 > 0 ? modules : nil, errors?.count ?? 0 > 0 ? errors : nil)
} }
} }