progress bar changes

This commit is contained in:
Panth Patel 2019-06-04 11:52:56 -04:00
commit 458cddb421
48 changed files with 903 additions and 209 deletions

View File

@ -10,9 +10,11 @@
0105618D224BBE7700E1557D /* FormValidator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618A224BBE7700E1557D /* FormValidator.swift */; };
0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */; };
0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */; };
016A1071228122180009D605 /* SwitchLineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 016A1070228122180009D605 /* SwitchLineItem.swift */; };
0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0198F79E225679870066C936 /* FormValidationProtocol.swift */; };
0198F7A62256A80B0066C936 /* MFRadioButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 0198F7A02256A80A0066C936 /* MFRadioButton.h */; settings = {ATTRIBUTES = (Public, ); }; };
0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 0198F7A22256A80A0066C936 /* MFRadioButton.m */; };
01CA51B5229716F60071A6EE /* Switch.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01CA51B4229716F60071A6EE /* Switch.swift */; };
01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */; };
01DF567021FA5AB300CC099B /* TextFieldListFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */; };
01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; };
@ -35,6 +37,9 @@
D282AACB2243C61700C46919 /* ButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AACA2243C61700C46919 /* ButtonView.swift */; };
D28B4F8A21FF967C00712C7A /* MVMCoreUIObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
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, ); }; };
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 */; };
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, ); }; };
D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770EE21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m */; };
@ -172,9 +177,11 @@
0105618A224BBE7700E1557D /* FormValidator.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidator.swift; sourceTree = "<group>"; };
0105618B224BBE7700E1557D /* FormValidator+TextFields.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+TextFields.swift"; sourceTree = "<group>"; };
0105618C224BBE7700E1557D /* FormValidator+FormParams.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FormValidator+FormParams.swift"; sourceTree = "<group>"; };
016A1070228122180009D605 /* SwitchLineItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwitchLineItem.swift; sourceTree = "<group>"; };
0198F79E225679870066C936 /* FormValidationProtocol.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FormValidationProtocol.swift; sourceTree = "<group>"; };
0198F7A02256A80A0066C936 /* MFRadioButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFRadioButton.h; sourceTree = "<group>"; };
0198F7A22256A80A0066C936 /* MFRadioButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFRadioButton.m; sourceTree = "<group>"; };
01CA51B4229716F60071A6EE /* Switch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Switch.swift; sourceTree = "<group>"; };
01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MFTextFieldListView.swift; sourceTree = "<group>"; };
01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldListFormViewController.swift; sourceTree = "<group>"; };
B8200E142280C4CF007245F4 /* ProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBar.swift; sourceTree = "<group>"; };
@ -196,6 +203,9 @@
D282AACA2243C61700C46919 /* ButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonView.swift; sourceTree = "<group>"; };
D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIObject.h; 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>"; };
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>"; };
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>"; };
D29770EE21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsAndBottomButtonsTableViewController.m; sourceTree = "<group>"; };
@ -415,6 +425,7 @@
01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */,
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */,
D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */,
D296E13B2295969C0051EBE7 /* MoleculeListCellProtocol.h */,
D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */,
);
path = Templates;
@ -446,6 +457,8 @@
D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */,
D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */,
D282AACA2243C61700C46919 /* ButtonView.swift */,
016A1070228122180009D605 /* SwitchLineItem.swift */,
01CA51B4229716F60071A6EE /* Switch.swift */,
D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */,
D2A514662213885800345BFB /* StandardHeaderView.swift */,
D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */,
@ -657,8 +670,10 @@
D29DF27421E79E81003B2FB9 /* MVMCoreUILoggingHandler.m */,
D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */,
D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */,
D296E1402295EBBA0051EBE7 /* MoleculeDelegateProtocol.h */,
D2A514562211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.h */,
D2A514572211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m */,
D296E142229729C30051EBE7 /* MoleculeMappingObject+Extension.swift */,
);
path = OtherHandlers;
sourceTree = "<group>";
@ -779,6 +794,7 @@
D29DF12D21E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.h in Headers */,
D29DF24E21E6A177003B2FB9 /* MFDigitTextField.h in Headers */,
D29770F321F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h in Headers */,
D296E1412295EBBA0051EBE7 /* MoleculeDelegateProtocol.h in Headers */,
D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */,
D29770FD21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h in Headers */,
D29DF17421E69E1F003B2FB9 /* MFCustomButton.h in Headers */,
@ -787,6 +803,7 @@
D29DF2A121E7AF4E003B2FB9 /* MVMCoreUIUtility.h in Headers */,
D29DF17621E69E1F003B2FB9 /* PrimaryButton.h in Headers */,
D29DF2C821E7BFC1003B2FB9 /* MFSizeObject.h in Headers */,
D296E13C229598BF0051EBE7 /* MoleculeListCellProtocol.h in Headers */,
D29DF32021ED0CBA003B2FB9 /* LabelView.h in Headers */,
D29770C921F7C4AE00B2F0D0 /* TopLabelsView.h in Headers */,
D29DF2E121E9240B003B2FB9 /* MVMCoreUIPanelProtocol.h in Headers */,
@ -920,10 +937,12 @@
D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */,
D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationController.m in Sources */,
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
D296E143229729C30051EBE7 /* MoleculeMappingObject+Extension.swift in Sources */,
01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */,
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */,
D29DF2C921E7BFC6003B2FB9 /* MFSizeObject.m in Sources */,
D29DF2C721E7BF57003B2FB9 /* MFTabBarInteractor.m in Sources */,
016A1071228122180009D605 /* SwitchLineItem.swift in Sources */,
D29DF29521E7ADB8003B2FB9 /* ProgrammaticScrollViewController.m in Sources */,
D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */,
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
@ -943,6 +962,7 @@
D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */,
D29DF25121E6A177003B2FB9 /* MFDigitTextBox.m in Sources */,
DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */,
01CA51B5229716F60071A6EE /* Switch.swift in Sources */,
0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */,
D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */,
D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */,

View File

@ -9,6 +9,7 @@
open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol {
//------------------------------------------------------
// MARK: - Constants
//------------------------------------------------------
@ -51,6 +52,9 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol {
changeCaretColor()
}
public func updateView(_ size: CGFloat) {
}
//------------------------------------------------------
// MARK: - Functions
//------------------------------------------------------
@ -110,7 +114,7 @@ open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol {
setTitleColor(disabledColor, for: .disabled)
}
@objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
@objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
setWithActionMap(json, delegateObject: delegateObject, additionalData: additionalData)
guard let dictionary = json else { return }

View File

@ -128,7 +128,7 @@
#pragma mark - MVMCoreUIMoleculeViewProtocol
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
NSString *color = [json string:KeyTextColor];
if (color) {
[self setTitleColor:[UIColor mfGetColorForHex:color] forState:UIControlStateNormal];

View File

@ -648,10 +648,8 @@
[self setAsStandardCustom];
}
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) {
[FormValidator setupValidationWithMolecule:self delegate:((MVMCoreUIDelegateObject *)delegateObject).formValidationProtocol];
}
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
[FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol];
self.primaryButtonType = PrimaryButtonTypeCustom;
NSString *color = [json string:@"fillColor"];

View File

@ -116,6 +116,7 @@
- (void)inputFromDatePickerFromDate:(nullable NSDate *)fromDate toDate:(nullable NSDate *)toDate showFromDateAsDefaultInput:(BOOL)show;
- (void)setDatePickerFromDate:(nullable NSDate *)fromDate toDate:(nullable NSDate *)toDate;
- (nonnull NSDate *)dismissDatePicker;
- (void)dismissPicker;
//get all enabled textfields, can be pairly used with the primary button's handleEnablingWithTextFields if you only want the enable testfield's validation to be tested
+ (nullable NSArray *)getEnabledTextfields:(nullable NSArray <MFTextField *>*)textFieldToDetermine;

View File

@ -181,6 +181,10 @@
return pickedDate;
}
- (void)dismissPicker {
[self.textField resignFirstResponder];
}
- (void)setErrorMessage:(NSString *)errorMessage {
[MVMCoreDispatchUtility performBlockOnMainThread:^{
@ -559,14 +563,14 @@
self.isMolecule = YES;
}
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) {
[FormValidator setupValidationWithMolecule:self delegate:((MVMCoreUIDelegateObject *)delegateObject).formValidationProtocol];
FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:((MVMCoreUIDelegateObject *)delegateObject).formValidationProtocol];
[FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol];
FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:delegateObject.formValidationProtocol];
[self setWithMap:json];
self.mfTextFieldDelegate = formValidator;
self.uiTextFieldDelegate = ((MVMCoreUIDelegateObject *)delegateObject).uiTextFieldDelegate;
self.uiTextFieldDelegate = delegateObject.uiTextFieldDelegate;
[MVMCoreUICommonViewsUtility addDismissToolbar:self.textField delegate:self.uiTextFieldDelegate];
}
}

View File

@ -103,7 +103,7 @@ open class CaretView: MFView {
defaultState()
}
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
// Configure class properties with JSON values
guard let dictionary = json else { return }

View File

@ -68,7 +68,7 @@ open class DashLine: MFView {
isHidden = false
}
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
// Configure class properties with JSON values

View File

@ -295,7 +295,7 @@ import MVMCore
// MARK: - Atomization
//------------------------------------------------------
@objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
@objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
Label.setUILabel(self, withJSON: json, delegate: delegateObject, additionalData: additionalData)
originalAttributedString = attributedText
}

View File

@ -73,7 +73,7 @@
}
}
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
[super setWithJSON:json delegateObject:delegateObject additionalData:additionalData];
[self.label setWithJSON:json delegateObject:delegateObject additionalData:additionalData];
}

View File

@ -734,7 +734,7 @@ extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol {
}
@objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
@objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
// Configure class properties with JSON values
guard let dictionary = json else { return }

View File

@ -197,13 +197,12 @@ import UIKit
if let imageName = json?.optionalStringForKey("image"), shouldLoadImage(withName: imageName, width: width) {
imageView.image = nil
imageView.animatedImage = nil
loadImage(withName: imageName, format: json?.optionalStringForKey("imageFormat"), width: NSNumber(value: Double(width)), height: nil)
loadImage(withName: imageName, format: json?.optionalStringForKey("imageFormat"), width: NSNumber(value: Double(width)), height: nil, customFallbackImage: json?.optionalStringForKey("fallbackImage"))
}
}
// MARK: - MVMCoreUIMoleculeViewProtocol functions
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) {
backgroundColor = UIColor.mfGet(forHex: backgroundColorString)

View File

@ -44,7 +44,7 @@
#pragma mark - MVMCoreUIMoleculeViewProtocol
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
self.json = json;
}

View File

@ -58,9 +58,9 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
return UIStackViewAlignmentLeading;
}
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
[FormValidator setupValidationWithMolecule:self delegate:((MVMCoreUIDelegateObject *)delegateObject).formValidationProtocol];
[FormValidator setupValidationWithMolecule:self delegate:delegateObject.formValidationProtocol];
self.delegate = delegateObject;
self.fieldKey = [json stringForKey:KeyFieldKey];
self.isRequired = [json boolForKey:KeyRequired];
@ -342,8 +342,10 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
[self.checkMark updateCheckSelected:NO animated:animated];
}
FormValidator *formValidator = ((MVMCoreUIDelegateObject *)self.delegate).formValidationProtocol.formValidatorModel;
[formValidator enableByValidation];
if (self.delegate && [self.delegate respondsToSelector:@selector(formValidationProtocol)] && [[self.delegate performSelector:@selector(formValidationProtocol)] respondsToSelector:@selector(formValidatorModel)]) {
FormValidator *formValidator = [[self.delegate performSelector:@selector(formValidationProtocol)] performSelector:@selector(formValidatorModel)];
[formValidator enableByValidation];
}
}
- (void)setColor:(nullable UIColor *)color forState:(UIControlState)state {

View File

@ -95,17 +95,21 @@
}
}
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
[super setWithJSON:json delegateObject:delegateObject additionalData:additionalData];
if (json) {
self.hidden = NO;
NSString *type = [json string:KeyType];
if ([type isEqualToString:@"standard"]) {
[self setSize:1];
} else if ([type isEqualToString:@"medium"]) {
[self setSize:2];
} else if ([type isEqualToString:@"heavy"]) {
[self setSize:4];
if ([type isEqualToString:@"none"]) {
self.hidden = YES;
} else {
self.hidden = NO;
if ([type isEqualToString:@"medium"]) {
[self setAsMedium];
} else if ([type isEqualToString:@"heavy"]) {
[self setAsHeavy];
} else {
[self setAsLight];
}
}
NSString *backgroundColor = [json string:KeyBackgroundColor];
if (backgroundColor) {

View File

@ -151,7 +151,7 @@
self.updateViewHorizontalDefaults = YES;
}
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
[super setWithJSON:json delegateObject:delegateObject additionalData:additionalData];
if (self.molecule) {
[self.molecule setWithJSON:json delegateObject:delegateObject additionalData:additionalData];

View File

@ -27,13 +27,14 @@
#import <MVMCoreUI/ButtonDelegateProtocol.h>
#import <MVMCoreUI/MFStyler.h>
#import <MVMCoreUI/MVMCoreUIDetailViewProtocol.h>
#import <MVMCoreUI/MoleculeDelegateProtocol.h>
@class MainMenuViewController;
@class MVMCoreUITabBarPageControlViewController;
@class MVMAnimationManager;
@class DelegateObject;
@interface MFViewController : UIViewController <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol, MVMCoreActionDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, MFTextFieldDelegate, ButtonDelegateProtocol, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MVMCoreUIDetailViewProtocol>
@interface MFViewController : UIViewController <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol, MVMCoreActionDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, MFTextFieldDelegate, ButtonDelegateProtocol, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MVMCoreUIDetailViewProtocol, MoleculeDelegateProtocol>
// Stores the load object that this screen was loaded with.
@property (nullable, strong, nonatomic) MVMCoreLoadObject *loadObject;

View File

@ -279,7 +279,7 @@
- (void)updateNavigationBarUI:(nonnull UINavigationController *)navigationController {
if (navigationController) {
[navigationController setNavigationBarHidden:[self navigationBarHidden] animated:NO];
[navigationController setNavigationBarHidden:[self navigationBarHidden] animated:YES];
[UIColor mfSetBackgroundColorForNavigationBar:[self navigationBarColor] navigationBar:navigationController.navigationBar transparent:[self navigationBarTransparent]];
@ -297,6 +297,7 @@
if (navigationController == [MVMCoreUISplitViewController mainSplitViewController].navigationController) {
// Update icons if main navigation controller.
[[MVMCoreUISession sharedGlobal].splitViewController setupPanels];
[self setMasterShouldBeAccessible:self.masterShouldBeAccessible];
[self setSupportShouldBeAccessible:self.supportShouldBeAccessible];
[self showBottomProgressBar];
@ -343,15 +344,24 @@
- (BOOL)isOverridingRightButton {
NSDictionary *rightPanelLinkDict = [self.loadObject.pageJSON dict:@"rightPanelButtonLink"];
if (rightPanelLinkDict) {
[[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:rightPanelLinkDict
additionalData:nil
delegateObject:[self delegateObject]];
[[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:rightPanelLinkDict additionalData:nil delegateObject:[self delegateObject]];
return YES;
} else {
return NO;
}
}
- (BOOL)isOverridingLeftButton {
NSDictionary *leftPanelLinkDict = [self.loadObject.pageJSON dict:@"leftPanelButtonLink"];
if (leftPanelLinkDict) {
[[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:leftPanelLinkDict additionalData:nil delegateObject:[self delegateObject]];
return YES;
} else {
return NO;
}
}
- (void)setSupportShouldBeAccessible:(BOOL)supportShouldBeAccessible {
MVMCoreUISplitViewController *splitViewController = [MVMCoreUISession sharedGlobal].splitViewController;
@ -777,6 +787,15 @@
}
}
#pragma mark - MoleculeDelegateProtocol
- (NSDictionary *)getModuleWithName:(NSString *)name {
if (!name) {
return nil;
}
return [self.loadObject.modulesJSON dict:name];
}
#pragma mark - adobe analytics
- (nullable NSArray <NSDictionary *> *)additionalActionsToTrackWithMainActionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData {

View File

@ -21,6 +21,12 @@ NS_ASSUME_NONNULL_BEGIN
- (void)panelWillDisappear:(nonnull NSObject <MVMCoreUIPanelProtocol>*)panel;
- (void)panelDidDisappear:(nonnull NSObject <MVMCoreUIPanelProtocol>*)panel;
/// Can override the left panel.
- (nullable UIViewController <MVMCoreUIPanelProtocol>*)overrideLeftPanel;
/// Can override the right panel.
- (nullable UIViewController <MVMCoreUIPanelProtocol>*)overrideRightPanel;
// Called when the back button is pressed. Overwrite for special functionality.
- (void)backButtonPressed;

View File

@ -6,7 +6,7 @@
// Copyright © 2017 Verizon Wireless. All rights reserved.
//
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
@protocol MVMCoreUIPanelProtocol <NSObject>
#pragma mark - life cycle
@ -33,6 +33,12 @@
- (void)showArrow;
- (void)hideArrow;
/// The width to use if the panel is automatically extended when the screen is big enough.
- (CGFloat)panelExtendedWidth;
/// The maximum width of the panel.
- (CGFloat)panelMaxWidth;
// Gets called when we are restarting or clearing a session.
- (void)clearData;

View File

@ -80,6 +80,9 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
// contains speicaly logic to set the icon color
- (void)setNavigationIconColor:(nullable UIColor *)color;
/// Updates the panels that are used.
- (void)setupPanels;
#pragma mark - Bottom Progress Bar
- (void)setBottomProgressBarProgress:(float)progress;
@ -114,7 +117,7 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
// Can subclass to set threshold for when the drawers are permanently extended. Default is 1000 for the left panel and 2000 for both.
- (MFNumberOfDrawers)numberOfDrawersShouldShow:(nullable NSNumber *)forWidth;
// subclass to return panels
// subclass to return default global panels. kept alive after creation.
- (nullable UIViewController <MVMCoreUIPanelProtocol> *)createLeftPanelViewController;
- (nullable UIViewController <MVMCoreUIPanelProtocol> *)createRightPanelViewController;

View File

@ -27,6 +27,12 @@
@interface MVMCoreUISplitViewController ()
typedef NS_OPTIONS(NSInteger, MFExtendedDrawer) {
MFExtendedDrawerNone = 0,
MFExtendedDrawerRight,
MFExtendedDrawerLeft
};
@property (weak, nonatomic) UIView *leftView;
@property (weak, nonatomic) UIView *mainView;
@property (weak, nonatomic) UIView *rightView;
@ -38,6 +44,10 @@
@property (weak, nonatomic) UIView *leftPanelSeparator;
@property (weak, nonatomic) UIView *rightPanelSeparator;
// For keeping
@property (strong, nonatomic, readwrite) UIViewController <MVMCoreUIPanelProtocol> *globalLeftPanel;
@property (strong, nonatomic, readwrite) UIViewController <MVMCoreUIPanelProtocol> *globalRightPanel;
@property (weak, nonatomic, readwrite) UIViewController <MVMCoreUIPanelProtocol> *leftPanel;
@property (weak, nonatomic, readwrite) UIViewController <MVMCoreUIPanelProtocol> *rightPanel;
@property (weak, nonatomic, readwrite) MVMCoreUINavigationController *navigationController;
@ -51,13 +61,7 @@
@property (nonatomic, strong) UIGestureRecognizer *tapToDismissGesture;
@property (nullable, readwrite, weak, nonatomic) NSObject <MVMCoreUIPanelProtocol> *explictlyShowingPanel;
@property (nullable, weak, nonatomic) NSObject <MVMCoreUIPanelProtocol> *prioritizedExtendedPanel;
typedef NS_OPTIONS(NSInteger, MFExtendedDrawer) {
MFExtendedDrawerNone = 0,
MFExtendedDrawerRight,
MFExtendedDrawerLeft
};
@property (nonatomic) MFExtendedDrawer prioritizedExtendedPanel;
@property (nonatomic) MFExtendedDrawer extendedDrawers;
@property (nonatomic, readwrite) BOOL leftPanelIsAccessible;
@ -119,18 +123,30 @@ CGFloat const PanelAnimationDuration = 0.2;
}
- (CGFloat)leftPanelExtendedWidth {
if ([self.leftPanel respondsToSelector:@selector(panelExtendedWidth)]) {
return [self.leftPanel panelExtendedWidth];
}
return 320;
}
- (CGFloat)leftPanelMaxWidth {
if ([self.leftPanel respondsToSelector:@selector(panelMaxWidth)]) {
return [self.leftPanel panelMaxWidth];
}
return 415;
}
- (CGFloat)rightPanelExtendedWidth {
if ([self.rightPanel respondsToSelector:@selector(panelExtendedWidth)]) {
return [self.rightPanel panelExtendedWidth];
}
return 320;
}
- (CGFloat)rightPanelMaxWidth {
if ([self.rightPanel respondsToSelector:@selector(panelMaxWidth)]) {
return [self.rightPanel panelMaxWidth];
}
return 500;
}
@ -217,7 +233,7 @@ CGFloat const PanelAnimationDuration = 0.2;
return NO;
} else {
// left is extended if the right panel isn't prioritized.
return self.prioritizedExtendedPanel != self.rightPanel;
return self.prioritizedExtendedPanel != MFExtendedDrawerRight;
}
}
}
@ -420,7 +436,7 @@ CGFloat const PanelAnimationDuration = 0.2;
return NO;
} else {
// Extend right if the left panel isn't prioritized.
return self.prioritizedExtendedPanel != self.leftPanel;
return self.prioritizedExtendedPanel != MFExtendedDrawerLeft;
}
}
}
@ -656,6 +672,98 @@ CGFloat const PanelAnimationDuration = 0.2;
}
}
- (void)addPanel:(nonnull UIViewController <MVMCoreUIPanelProtocol> *)panel {
UIView *view = panel.view;
[self addChildViewController:panel];
[self.view addSubview:view];
[panel didMoveToParentViewController:self];
}
- (void)removePanel:(nullable UIViewController <MVMCoreUIPanelProtocol> *)panel {
[panel willMoveToParentViewController:nil];
[panel.view removeFromSuperview];
[panel removeFromParentViewController];
}
- (void)setupLeftPanel {
UIViewController <MVMCoreUIPanelProtocol> *panel = nil;
UIViewController *currentViewController = [self getCurrentDetailViewController];
if ([currentViewController respondsToSelector:@selector(overrideLeftPanel)]) {
panel = [((UIViewController <MVMCoreUIDetailViewProtocol> *)currentViewController) overrideLeftPanel];
} else {
panel = self.globalLeftPanel;
self.leftPanelButton = nil;
}
if (!panel) {
[self removePanel:self.leftPanel];
} else if (panel && panel != self.leftPanel) {
[self removePanel:self.leftPanel];
[self addPanel:panel];
self.leftView = panel.view;
self.leftPanel = panel;
self.leftView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *leftPanelWidth = [NSLayoutConstraint constraintWithItem:self.leftView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:270];
self.leftView.translatesAutoresizingMaskIntoConstraints = NO;
leftPanelWidth.active = YES;
self.leftPanelWidth = leftPanelWidth;
[NSLayoutConstraint constraintWithItem:self.mainView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.leftView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:self.leftView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:self.leftView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES;
if ([panel respondsToSelector:@selector(buttonForPanel)]) {
self.leftPanelButton = [panel buttonForPanel];
} else if ([panel respondsToSelector:@selector(imageForButtonForPanel)]) {
self.leftPanelButton = [[UIBarButtonItem alloc] initWithImage:[panel imageForButtonForPanel] style:UIBarButtonItemStylePlain target:self action:@selector(leftPanelButtonPressed:)];
} else {
self.leftPanelButton = nil;
}
}
}
- (void)setupRightPanel {
UIViewController <MVMCoreUIPanelProtocol> *panel = nil;
UIViewController *currentViewController = [self getCurrentDetailViewController];
if ([currentViewController respondsToSelector:@selector(overrideRightPanel)]) {
panel = [((UIViewController <MVMCoreUIDetailViewProtocol> *)currentViewController) overrideRightPanel];
} else {
panel = self.globalRightPanel;
}
if (!panel) {
[self removePanel:self.rightPanel];
self.rightPanelButton = nil;
} else if (panel && panel != self.rightPanel) {
[self removePanel:self.rightPanel];
[self addPanel:panel];
self.rightView = panel.view;
self.rightPanel = panel;
self.rightView.translatesAutoresizingMaskIntoConstraints = NO;
NSLayoutConstraint *rightPanelWidth = [NSLayoutConstraint constraintWithItem:self.rightView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:270];
rightPanelWidth.active = YES;
self.rightPanelWidth = rightPanelWidth;
[NSLayoutConstraint constraintWithItem:self.rightView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:self.rightView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:self.rightView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self.mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES;
if ([panel respondsToSelector:@selector(buttonForPanel)]) {
self.rightPanelButton = [panel buttonForPanel];
} else if ([panel respondsToSelector:@selector(imageForButtonForPanel)]) {
self.rightPanelButton = [[UIBarButtonItem alloc] initWithImage:[panel imageForButtonForPanel] style:UIBarButtonItemStylePlain target:self action:@selector(rightPanelButtonPressed:)];
} else {
self.rightPanelButton = nil;
}
}
}
- (void)setupPanels {
[self forceHideBothDrawers];
[self setupLeftPanel];
[self setupRightPanel];
self.explictlyShowingPanel = nil;
[self.view layoutIfNeeded];
}
#pragma mark - Bottom Progress Bar
- (void)setBottomProgressBarProgress:(float)progress {
@ -744,62 +852,16 @@ CGFloat const PanelAnimationDuration = 0.2;
[NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:coverView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES;
// Left Panel
UIViewController <MVMCoreUIPanelProtocol> *leftPanel = [self createLeftPanelViewController];
if (leftPanel) {
UIView *leftView = leftPanel.view;
[self addChildViewController:leftPanel];
[self.view addSubview:leftView];
[leftPanel didMoveToParentViewController:self];
self.leftView = leftView;
self.leftPanel = leftPanel;
NSLayoutConstraint *leftPanelWidth = [NSLayoutConstraint constraintWithItem:leftView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:270];
leftPanelWidth.active = YES;
self.leftPanelWidth = leftPanelWidth;
[NSLayoutConstraint constraintWithItem:mainView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:leftView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:leftView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:leftView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES;
}
// Right Panel
UIViewController <MVMCoreUIPanelProtocol> *rightPanel = [self createRightPanelViewController];
if (rightPanel) {
UIView *rightView = rightPanel.view;
[self addChildViewController:rightPanel];
[self.view addSubview:rightView];
[rightPanel didMoveToParentViewController:self];
self.rightView = rightView;
self.rightPanel = rightPanel;
NSLayoutConstraint *rightPanelWidth = [NSLayoutConstraint constraintWithItem:rightView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:270];
rightPanelWidth.active = YES;
self.rightPanelWidth = rightPanelWidth;
[NSLayoutConstraint constraintWithItem:rightView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:rightView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0].active = YES;
[NSLayoutConstraint constraintWithItem:rightView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:mainView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0].active = YES;
}
// Create panels
self.globalLeftPanel = [self createLeftPanelViewController];
self.globalRightPanel = [self createRightPanelViewController];
[self setupPanels];
}
- (void)viewDidLoad {
[super viewDidLoad];
[self.topAlertView pinATopViewController:self];
// Do any additional setup after loading the view.
if (self.leftPanel) {
if ([self.leftPanel respondsToSelector:@selector(buttonForPanel)]) {
self.leftPanelButton = [self.leftPanel buttonForPanel];
} else {
self.leftPanelButton = [[UIBarButtonItem alloc] initWithImage:[self.leftPanel imageForButtonForPanel] style:UIBarButtonItemStylePlain target:self action:@selector(leftPanelButtonPressed:)];
}
}
if (self.rightPanel) {
if ([self.rightPanel respondsToSelector:@selector(buttonForPanel)]) {
self.rightPanelButton = [self.rightPanel buttonForPanel];
} else {
self.rightPanelButton = [[UIBarButtonItem alloc] initWithImage:[self.rightPanel imageForButtonForPanel] style:UIBarButtonItemStylePlain target:self action:@selector(rightPanelButtonPressed:)];
}
}
// Creates the back button
self.backButton = [[UIBarButtonItem alloc] initWithImage:[self imageForBackButton] style:UIBarButtonItemStylePlain target:self action:@selector(backButtonPressed:)];
self.backButton.imageInsets = UIEdgeInsetsMake(0, 4, 0, -8);
@ -811,7 +873,7 @@ CGFloat const PanelAnimationDuration = 0.2;
}
self.extendedDrawers = MFExtendedDrawerLeft | MFExtendedDrawerRight;
self.prioritizedExtendedPanel = self.leftPanel;
self.prioritizedExtendedPanel = MFExtendedDrawerLeft;
self.view.backgroundColor = [UIColor blackColor];
}

View File

@ -139,6 +139,22 @@
}
}
- (BOOL)isOverridingLeftButton {
if ([self.viewController respondsToSelector:@selector(isOverridingLeftButton)]) {
return [self.viewController performSelector:@selector(isOverridingLeftButton)];
} else {
return [super isOverridingLeftButton];
}
}
- (BOOL)isOverridingRightButton {
if ([self.viewController respondsToSelector:@selector(isOverridingRightButton)]) {
return [self.viewController performSelector:@selector(isOverridingRightButton)];
} else {
return [super isOverridingRightButton];
}
}
#pragma mark - View Cycle
- (void)loadView {

View File

@ -20,6 +20,8 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[];
#import <MVMCoreUI/MVMCoreUISession.h>
#import <MVMCoreUI/MVMCoreUILoggingHandler.h>
#import <MVMCoreUI/MVMCoreUIViewControllerMappingObject.h>
#import <MVMCoreUI/MoleculeDelegateProtocol.h>
#import <MVMCoreUI/MoleculeListCellProtocol.h>
#import <MVMCoreUI/MVMCoreUIMoleculeMappingObject.h>
#pragma mark - TopAlert

View File

@ -33,7 +33,7 @@ import UIKit
primaryButton?.isEnabled = enabled
}
public init(withJSON json: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
public init(withJSON json: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) {
super.init(frame: .zero)
setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
}
@ -58,11 +58,15 @@ import UIKit
primaryButton?.setAsMolecule()
}
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
primaryButton?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
}
public override static func estimatedHeight(forRow json: [AnyHashable : Any]?) -> CGFloat {
return 42
}
// MARK: - Constraining
func setupButton() {
if let primaryButton = primaryButton, !subviews.contains(primaryButton) {

View File

@ -7,12 +7,13 @@
//
#import <UIKit/UIKit.h>
@class DelegateObject;
@import MVMCore.MVMCoreViewProtocol;
@class MVMCoreUIDelegateObject;
@protocol MVMCoreUIMoleculeViewProtocol <NSObject>
@protocol MVMCoreUIMoleculeViewProtocol <NSObject, MVMCoreViewProtocol>
// Sets up the ui based on the json
- (void)setWithJSON:(nullable NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData;
- (void)setWithJSON:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData;
@optional
@ -26,7 +27,7 @@
- (UIStackViewAlignment)moleculeAlignment;
// For the molecule list to load more efficiently.
+ (CGFloat)estimatedHeightForRow;
+ (CGFloat)estimatedHeightForRow:(nullable NSDictionary *)json;
@end

View File

@ -18,12 +18,12 @@ public class MoleculeStackView: MFView {
super.init(frame: frame)
}
public init(withJSON json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) {
public init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
super.init(frame: CGRect.zero)
setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
}
public convenience init(withJSON json: [AnyHashable: Any]?, delegateObject: DelegateObject?, spacingBlock: ((Any) -> UIEdgeInsets)?) {
public convenience init(withJSON json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, spacingBlock: ((Any) -> UIEdgeInsets)?) {
self.init(withJSON: json, delegateObject: delegateObject, additionalData: nil)
self.spacingBlock = spacingBlock
}
@ -51,7 +51,7 @@ public class MoleculeStackView: MFView {
}
// MARK: - MVMCoreUIMoleculeViewProtocol
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
guard let molecules = json?.arrayForKey(KeyMolecules) as? [[String: Any]] else {
return
@ -60,7 +60,7 @@ public class MoleculeStackView: MFView {
// Create the molecules and set the json.
var moleculesArray = [] as [UIView]
for moleculeJSON in molecules {
if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject) {
if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: true) {
moleculesArray.append(molecule)
}
}

View File

@ -8,8 +8,10 @@
import UIKit
@objcMembers open class MoleculeTableViewCell: UITableViewCell, MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol {
@objcMembers open class MoleculeTableViewCell: UITableViewCell, MVMCoreUIMoleculeViewProtocol, MoleculeListCellProtocol {
open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)?
open var json: [AnyHashable: Any]?
// For the accessory view convenience.
public var caretView: CaretView?
@ -50,9 +52,7 @@ import UIKit
bottomSeparatorView?.setLeftAndRightPinConstant(layoutMargins.left)
}
if let molecule = molecule as? MVMCoreViewProtocol {
molecule.updateView(size)
}
molecule?.updateView(size)
if let _ = accessoryView, let caretView = caretView, let widthObject = caretViewWidthSizeObject, let heightObject = caretViewHeightSizeObject {
caretView.frame = CGRect(x: 0, y: 0, width: widthObject.getValueBased(onSize: size), height: heightObject.getValueBased(onSize: size))
}
@ -67,23 +67,46 @@ import UIKit
}
// MARK: - MVMCoreUIMoleculeViewProtocol
public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) {
guard let json = json else {
public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
self.json = json;
guard let json = json, let moleculeJSON = json.optionalDictionaryForKey(KeyMolecule) else {
return
}
if molecule == nil {
if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: json, delegateObject: delegateObject) {
if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject, constrainIfNeeded: true) {
contentView.addSubview(moleculeView)
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: moleculeView.needsToBeConstrained?() ?? false).values))
molecule = moleculeView
}
} else {
molecule?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
molecule?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData)
}
backgroundColor = molecule?.backgroundColor
// Add the caret if there is an action and it's not declared hidden.
if let _ = json.optionalDictionaryForKey("actionMap"), !json.boolForKey("hideArrow") {
addCaretViewAccessory()
} else {
accessoryView = nil
}
// override the separator
if let separator = json.optionalDictionaryForKey("separator") {
addSeparatorsIfNeeded()
bottomSeparatorView?.setWithJSON(separator, delegateObject: delegateObject, additionalData: additionalData)
}
}
// MARK: - Convenience
public static func estimatedHeight(forRow json: [AnyHashable : Any]?) -> CGFloat {
guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule),
let theClass = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON, delegateObject: nil),
let estimatedHeightFor = theClass.estimatedHeight else {
return 0
}
return estimatedHeightFor(moleculeJSON)
}
// MARK: - Arrow
/// Adds the standard mvm style caret to the accessory view
public func addCaretViewAccessory() {
guard accessoryView == nil else {
@ -98,6 +121,34 @@ import UIKit
accessoryView = caretView
}
// MARK: - MoleculeListCellProtocol
public static func moleculeName(_ molecule: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? {
return molecule?.optionalDictionaryForKey(KeyMolecule)?.optionalStringForKey(KeyMoleculeName)
}
/// For when the separator between cells shows using json and frequency. Default is type: standard, frequency: allExceptTop.
public func setSeparatorWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?, indexPath: IndexPath) {
addSeparatorsIfNeeded()
if let json = json {
topSeparatorView?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
bottomSeparatorView?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
if let separatorFrequencyString = json.optionalStringForKey("frequency"), let separatorFrequency = SeparatorFrequency(rawValue: separatorFrequencyString) {
setSeparatorFrequency(separatorFrequency, indexPath: indexPath)
}
} else {
topSeparatorView?.hide()
bottomSeparatorView?.setAsLight()
setSeparatorFrequency(MoleculeTableViewCell.SeparatorFrequency.AllExceptTop, indexPath: indexPath)
}
}
public func didSelectCell(atIndex indexPath: IndexPath, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
if let actionMap = json?.optionalDictionaryForKey("actionMap") {
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
}
}
// MARK: - Separator
func addSeparatorsIfNeeded() {
if topSeparatorView == nil {
topSeparatorView = SeparatorView.separatorAdd(to: self, position: SeparatorPositionTop)
@ -109,19 +160,6 @@ import UIKit
}
}
/// For when the separator between cells shows using json and frequency.
public func setSeparatorWithJSON(_ json: [AnyHashable : Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?, indexPath: IndexPath) {
guard let json = json else {
return
}
addSeparatorsIfNeeded()
topSeparatorView?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
bottomSeparatorView?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
if let separatorFrequencyString = json.optionalStringForKey("frequency"), let separatorFrequency = SeparatorFrequency(rawValue: separatorFrequencyString) {
setSeparatorFrequency(separatorFrequency, indexPath: indexPath)
}
}
/// For when the separator between cells shows.
public func setSeparatorFrequency(_ separatorFrequency: SeparatorFrequency, indexPath: IndexPath) {
switch separatorFrequency {

View File

@ -8,7 +8,7 @@
import Foundation
public class ProgressBar: UIProgressView, MVMCoreUIMoleculeViewProtocol {
public class ProgressBar: UIProgressView {
var isRounded = Bool()
var thickness : Float = 0.0 {
@ -24,7 +24,7 @@ public class ProgressBar: UIProgressView, MVMCoreUIMoleculeViewProtocol {
}
}
open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
isRounded = json?.optionalBoolForKey("roundedRect") ?? false
thickness = json?.floatFromStringForKey("thickness") ?? Float(0.0)
let percentage = json?.floatFromStringForKey("percent")

View File

@ -20,7 +20,7 @@ import UIKit
return true
}
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
progress.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)

View File

@ -93,7 +93,7 @@ public class StandardFooterView: ViewConstrainingView {
layoutIfNeeded()
}
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
if let colorString = json?.optionalStringForKey(KeyBackgroundColor) {
backgroundColor = .mfGet(forHex: colorString)

View File

@ -110,7 +110,7 @@ public class StandardHeaderView: ViewConstrainingView {
separatorView?.rightPin?.constant = constant
}
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
if let colorString = json?.optionalStringForKey(KeyBackgroundColor) {
backgroundColor = .mfGet(forHex: colorString)

View File

@ -0,0 +1,87 @@
//
// Switch.swift
// MVMCoreUI
//
// Created by Priya on 5/23/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import UIKit
@objcMembers public class Switch: ViewConstrainingView, FormValidationProtocol{
public var mvmSwitch = MVMCoreUISwitch()
var isRequired = false
var delegateObject: DelegateObject?
@objc func switchChanged() {
let delegate = delegateObject as? MVMCoreUIDelegateObject
if let delegate = delegate {
let formValidator = delegate.formValidationProtocol?.formValidatorModel?()
formValidator?.enableByValidation()
}
}
open override func setupView() {
super.setupView()
mvmSwitch.addTarget(self, action: #selector(Switch.switchChanged), for: .valueChanged)
self.clipsToBounds = true
addSubview(mvmSwitch)
mvmSwitch.translatesAutoresizingMaskIntoConstraints = false
setupContainerConstraints()
}
public override func updateView(_ size: CGFloat) {
super.updateView(size)
mvmSwitch.updateView(size)
}
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
isRequired = json?[KeyRequired] as? Bool ?? false
self.delegateObject = delegateObject
if let delegateObject = delegateObject {
FormValidator.setupValidation(molecule: self, delegate: delegateObject.formValidationProtocol)
}
if let onColorString = json?.optionalStringForKey("onTintColor") {
mvmSwitch.onTintColor = .mfGet(forHex: onColorString)
}
if let offColorString = json?.optionalStringForKey("offTintColor") {
mvmSwitch.offTintColor = .mfGet(forHex: offColorString)
}
if let onKnobColorString = json?.optionalStringForKey("onKnobTintColor") {
mvmSwitch.onKnobTintColor = .mfGet(forHex: onKnobColorString)
}
if let offKnobColorString = json?.optionalStringForKey("offKnobTintColor") {
mvmSwitch.offKnobTintColor = .mfGet(forHex: offKnobColorString)
}
mvmSwitch.setState(json?.optionalBoolForKey("state") ?? false, animated: true)
}
func setupContainerConstraints() {
mvmSwitch.topAnchor.constraint(equalTo: topAnchor).isActive = true
mvmSwitch.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
mvmSwitch.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
mvmSwitch.trailingAnchor.constraint(equalTo: trailingAnchor).isActive = true
}
public func isValidField() -> Bool {
return (isRequired == false) ? true : mvmSwitch.isOn
}
public func formFieldName() -> String? {
return json?.optionalStringForKey(KeyFieldKey)
}
public func formFieldValue() -> Any? {
return mvmSwitch.isOn
}
public override func needsToBeConstrained() -> Bool {
return true
}
public override func moleculeAlignment() -> UIStackView.Alignment {
return UIStackView.Alignment.leading
}
}

View File

@ -0,0 +1,121 @@
//
// SwitchLineItem.swift
// MVMCoreUI
//
// Created by Priya on 5/6/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
import UIKit
@objcMembers public class SwitchLineItem: ViewConstrainingView, FormValidationProtocol{
public var mvmSwitch = Switch()
public var label = Label()
public var leftContainerView = UIView()
public var mfTextButton = MFTextButton(nil, constrainHeight: true, forWidth: 0)
var isRequired = false
var delegateObject: DelegateObject?
@objc func switchChanged() {
let delegate = delegateObject as? MVMCoreUIDelegateObject
if let delegate = delegate {
let formValidator = delegate.formValidationProtocol?.formValidatorModel?()
formValidator?.enableByValidation()
}
}
open override func setupView() {
super.setupView()
leftContainerView.addSubview(label)
leftContainerView.addSubview(mfTextButton)
addSubview(leftContainerView)
addSubview(mvmSwitch)
leftContainerView.translatesAutoresizingMaskIntoConstraints = false
mvmSwitch.translatesAutoresizingMaskIntoConstraints = false
mfTextButton.translatesAutoresizingMaskIntoConstraints = false
label.translatesAutoresizingMaskIntoConstraints = false
setupContainerConstraints()
}
public override func updateView(_ size: CGFloat) {
super.updateView(size)
label.updateView(size)
mvmSwitch.updateView(size)
mfTextButton.updateView(size)
}
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
mvmSwitch.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
label.setWithJSON(json?.optionalDictionaryForKey("label"), delegateObject: delegateObject, additionalData: additionalData)
mfTextButton.setWithJSON(json?.optionalDictionaryForKey("textButton"), delegateObject: delegateObject, additionalData: additionalData)
if (label.text?.count ?? 0) <= 0 && (mfTextButton.titleLabel?.text?.count ?? 0) <= 0 {
mvmSwitch.leadingAnchor.constraint(equalTo: leadingAnchor, constant: 0).isActive = true
}
}
func setupContainerConstraints() {
leftContainerView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true
var constraint = leftContainerView.topAnchor.constraint(equalTo: topAnchor)
constraint.priority = UILayoutPriority(249)
constraint.isActive = true
mvmSwitch.topAnchor.constraint(greaterThanOrEqualTo: topAnchor).isActive = true
constraint = mvmSwitch.topAnchor.constraint(equalTo: topAnchor)
constraint.priority = UILayoutPriority(249)
constraint.isActive = true
trailingAnchor.constraint(equalTo: mvmSwitch.trailingAnchor).isActive = true
constraint = bottomAnchor.constraint(equalTo: mvmSwitch.bottomAnchor)
constraint.priority = UILayoutPriority(249)
constraint.isActive = true
bottomAnchor.constraint(greaterThanOrEqualTo: mvmSwitch.bottomAnchor).isActive = true
constraint = bottomAnchor.constraint(equalTo: leftContainerView.bottomAnchor)
constraint.isActive = true
bottomAnchor.constraint(greaterThanOrEqualTo: leftContainerView.bottomAnchor).isActive = true
leftContainerView.leadingAnchor.constraint(equalTo: leadingAnchor).isActive = true
NSLayoutConstraint.constraintPinSubview(leftContainerView, pinCenterX: false, pinCenterY: true)
constraint = mvmSwitch.leadingAnchor.constraint(greaterThanOrEqualTo: leftContainerView.trailingAnchor)
constraint.priority = UILayoutPriority(999)
constraint.isActive = true
NSLayoutConstraint.constraintPinSubview(mvmSwitch, pinCenterX: false, pinCenterY: true)
leftContainerView.topAnchor.constraint(equalTo: label.topAnchor).isActive = true
leftContainerView.trailingAnchor.constraint(greaterThanOrEqualTo: label.trailingAnchor).isActive = true
constraint = leftContainerView.trailingAnchor.constraint(equalTo: label.trailingAnchor)
constraint.priority = UILayoutPriority(249)
constraint.isActive = true
leftContainerView.trailingAnchor.constraint(greaterThanOrEqualTo: mfTextButton.trailingAnchor).isActive = true
constraint = leftContainerView.trailingAnchor.constraint(equalTo: mfTextButton.trailingAnchor)
constraint.priority = UILayoutPriority(249)
constraint.isActive = true
leftContainerView.bottomAnchor.constraint(equalTo: mfTextButton.bottomAnchor).isActive = true
mfTextButton.leadingAnchor.constraint(equalTo: leftContainerView.leadingAnchor).isActive = true
label.leadingAnchor.constraint(equalTo: leftContainerView.leadingAnchor).isActive = true
mfTextButton.topAnchor.constraint(equalTo: label.bottomAnchor).isActive = true
leftContainerView.setContentHuggingPriority(.defaultHigh, for: .horizontal)
mvmSwitch.setContentHuggingPriority(.defaultLow, for: .horizontal)
}
public override func needsToBeConstrained() -> Bool {
return true
}
public override func moleculeAlignment() -> UIStackView.Alignment {
return UIStackView.Alignment.leading
}
}

View File

@ -39,7 +39,7 @@ import UIKit
}
// MARK: - MVMCoreUIMoleculeViewProtocol
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) {
backgroundColor = UIColor.mfGet(forHex: backgroundColorString)
@ -142,7 +142,7 @@ import UIKit
}
}
open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) {
setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON, legacy: false)
setDefaultCustom()
primaryButton?.setWithJSON(primaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData)

View File

@ -12,11 +12,17 @@ open class MVMCoreUIDelegateObject: DelegateObject {
public weak var formValidationProtocol: FormValidationProtocol?
public weak var buttonDelegate: ButtonDelegateProtocol?
public weak var uiTextFieldDelegate: UITextFieldDelegate?
public weak var moleculeDelegate: MoleculeDelegateProtocol?
open override func setAll(withDelegate delegate: Any) {
super.setAll(withDelegate: delegate)
formValidationProtocol = delegate as? FormValidationProtocol
buttonDelegate = delegate as? ButtonDelegateProtocol
uiTextFieldDelegate = delegate as? UITextFieldDelegate
moleculeDelegate = delegate as? MoleculeDelegateProtocol
}
class func delegateObject(from controller: MVMCoreViewControllerProtocol?) -> MVMCoreUIDelegateObject? {
return controller?.delegateObject?() as? MVMCoreUIDelegateObject
}
}

View File

@ -8,21 +8,35 @@
#import <UIKit/UIKit.h>
#import <MVMCoreUI/MVMCoreUIMoleculeViewProtocol.h>
@class DelegateObject;
@class MVMCoreUIDelegateObject;
@class MVMCoreLoadObject;
@class MVMCoreErrorObject;
@interface MVMCoreUIMoleculeMappingObject : NSObject
// Maps molecule name to class.
@property (nullable, strong, nonatomic) NSMutableDictionary <NSString *, Class> *moleculeMapping;
/// Maps molecule name to class.
@property (nonnull, strong, nonatomic) NSMutableDictionary <NSString *, Class> *moleculeMapping;
// Returns the shared instance
/// Returns the shared instance
+ (nullable instancetype)sharedMappingObject;
// Returns the molecule for the given name.
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForName:(nonnull NSString *)name;
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject;
/// Returns the molecule class.
- (nullable Class)getMoleculeClassWithJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject;
// Similar to above but also checks if the molecule needs to be constrained for a stack.
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForStackWithJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject;
#pragma mark - Molecule Creation
/// Creates the molecule for the given name.
- (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;
/// 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.
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject constrainIfNeeded:(BOOL)constrainIfNeeded;
#pragma mark - ModuleMolecule Helpers
/// If the molecule is a module molecule, will get the map for the molecule to load from a module. Otherwise nil.
+ (nullable NSDictionary *)getMoleculeMapForModuleMolecule:(nullable NSDictionary *)moduleMolecule delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject error:(MVMCoreErrorObject *_Nullable *_Nullable)error;
@end

View File

@ -9,6 +9,7 @@
#import "MVMCoreUIMoleculeMappingObject.h"
@import MVMCore.MVMCoreActionUtility;
@import MVMCore.NSDictionary_MFConvenience;
@import MVMCore.MVMCoreLoadObject;
#import "MVMCoreUIObject.h"
#import <MVMCoreUI/MVMCoreUI-Swift.h>
#import "MFTextField.h"
@ -35,7 +36,12 @@
@"textField" : MFTextField.class,
@"checkbox" : MVMCoreUICheckBox.class,
@"progressBarView" : ProgressBarView.class,
@"progressBar": ProgressBar.class
@"progressBar": ProgressBar.class,
@"textField": MFTextField.class,
@"checkbox": MVMCoreUICheckBox.class,
@"listItem": MoleculeTableViewCell.class,
@"switchLineItem": SwitchLineItem.class,
@"switch": Switch.class
} mutableCopy];
});
return mapping;
@ -46,7 +52,18 @@
return [MVMCoreActionUtility initializerClassCheck:[MVMCoreUIObject sharedInstance].moleculeMap classToVerify:self];
}
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForName:(nonnull NSString *)name {
- (nullable Class)getMoleculeClassWithJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject {
NSDictionary *moleculeJSON = [MVMCoreUIMoleculeMappingObject getMoleculeMapForModuleMolecule:json delegateObject:delegateObject error:nil] ?: json;
NSString *moleculeName = [moleculeJSON string:KeyMoleculeName];
if (moleculeName) {
return [self.moleculeMapping objectForKey:moleculeName];
}
return nil;
}
#pragma mark - Molecule Creation
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForName:(nonnull NSString *)name {
Class class = [self.moleculeMapping objectForKey:name];
if (!class) {
return nil;
@ -58,28 +75,38 @@
return molecule;
}
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject {
NSString *moleculeName = [json string:KeyMoleculeName];
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)createMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject {
return [self createMoleculeForJSON:json delegateObject:delegateObject constrainIfNeeded:NO];
}
- (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 = [moleculeJSON string:KeyMoleculeName];
if (!moleculeName) {
return nil;
}
UIView <MVMCoreUIMoleculeViewProtocol>*molecule = [self getMoleculeForName:moleculeName];
[molecule setWithJSON:json delegateObject:delegateObject additionalData:nil];
UIView <MVMCoreUIMoleculeViewProtocol>*molecule = [self createMoleculeForName:moleculeName];
if (constrainIfNeeded && [molecule respondsToSelector:@selector(needsToBeConstrained)] && [molecule needsToBeConstrained]) {
molecule = [[ViewConstrainingView alloc] initWithMolecule:molecule alignment:[molecule respondsToSelector:@selector(moleculeAlignment)] ? [molecule moleculeAlignment] : UIStackViewAlignmentFill];
}
[molecule setWithJSON:moleculeJSON delegateObject:delegateObject additionalData:nil];
return molecule;
}
#pragma mark - ModuleMolecule Helpers
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForStackWithJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject {
NSString *moleculeName = [json string:KeyMoleculeName];
if (!moleculeName) {
+ (nullable NSDictionary *)getMoleculeMapForModuleMolecule:(nullable NSDictionary *)moduleMolecule delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject error:(MVMCoreErrorObject *_Nullable *_Nullable)error {
NSString *moleculeName = [moduleMolecule string:KeyMoleculeName];
if ([moleculeName isEqualToString:@"moduleMolecule"]) {
NSString *moduleName = [moduleMolecule string:@"moduleName"];
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 {
return nil;
}
UIView <MVMCoreUIMoleculeViewProtocol>*molecule = [self getMoleculeForName:moleculeName];
if ([molecule respondsToSelector:@selector(needsToBeConstrained)] && [molecule needsToBeConstrained]) {
molecule = [[ViewConstrainingView alloc] initWithMolecule:molecule alignment:[molecule respondsToSelector:@selector(moleculeAlignment)] ? [molecule moleculeAlignment] : UIStackViewAlignmentFill];
}
[molecule setWithJSON:json delegateObject:delegateObject additionalData:nil];
return molecule;
}
@end

View File

@ -0,0 +1,15 @@
//
// MoleculeDelegateProtocol.h
// MVMCoreUI
//
// Created by Scott Pfeil on 5/22/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
#import <UIKit/UIKit.h>
@protocol MoleculeDelegateProtocol <NSObject>
/// returns a module for the corresponding module name.
- (nullable NSDictionary *)getModuleWithName:(nullable NSString *)name;
@end

View File

@ -0,0 +1,47 @@
//
// 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

@ -157,6 +157,13 @@ B3 -> Legal
//75Bd 10pt only for support
+ (nullable UIFont *)fontForUnreadMessageOnSupport;
//55Rg 16pt for 5G flow
+ (nullable UIFont *)font5GMessage:(BOOL)genericScaling;
//55Rg 16pt for 5G flow scale YES
+ (nullable UIFont *)font5GMessage;
// Returns the fonts for these styles allowing to apply a generic scale by device or not.
+ (nullable UIFont *)fontForBiggerHeadLine:(BOOL)genericScaling;
+ (nullable UIFont *)fontForPlan:(BOOL)genericScaling;

View File

@ -347,6 +347,19 @@ CGFloat const LabelWithInternalButtonLineSpace = 2;
return [MFFonts mfFont75Bd:size];
}
+ (nullable UIFont *)font5GMessage:(BOOL)genericScaling {
CGFloat size = 16;
if (genericScaling) {
size = [self sizeFontGenericForCurrentDevice:size];
}
return [MFFonts mfFont55Rg:size];
}
+ (nullable UIFont *)font5GMessage {
return [self font5GMessage:YES];
}
+ (nullable UIFont *)fontForHeadlineAlternative:(BOOL)genericScaling {
CGFloat size = 24;
if (genericScaling) {

View File

@ -0,0 +1,22 @@
//
// MoleculeListCellProtocol.h
// MVMCoreUI
//
// Created by Scott Pfeil on 5/22/19.
// Copyright © 2019 Verizon Wireless. All rights reserved.
//
#import <UIKit/UIKit.h>
@class MVMCoreUIDelegateObject;
@protocol MoleculeListCellProtocol <NSObject>
@optional
/// Can override the molecule name for the given molecule. Otherwise we assume value for key moleculeName.
+ (nullable NSString *)moleculeName:(nullable NSDictionary *)molecule delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject;
/// Can set the separator according to what the moleculeList commands.
- (void)setSeparatorWithJSON:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData indexPath:(nonnull NSIndexPath *)indexPath;
/// Handle action
- (void)didSelectCellAtIndex:(nonnull NSIndexPath *)indexPath delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData;
@end

View File

@ -9,28 +9,33 @@
import UIKit
open class MoleculeListTemplate: ThreeLayerTableViewController {
var molecules: [(molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)]?
open override func registerWithTable() {
super.registerWithTable()
guard let molecules = loadObject?.pageJSON?.arrayForKey(KeyMolecules) else {
return
open override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
var shouldFinish = super.shouldFinishProcessingLoad(loadObject, error: error)
guard shouldFinish else {
return shouldFinish
}
for case let molecule as Dictionary<AnyHashable, Any> in molecules {
if let moleculeName = molecule.optionalStringForKey(KeyMoleculeName) {
tableView?.register(MoleculeTableViewCell.self, forCellReuseIdentifier: moleculeName)
}
if let firstError = setup()?.first {
// Don't continue if there was an error loading needed modules.
error.pointee = firstError
shouldFinish = false
}
return shouldFinish
}
open override func viewForTop() -> UIView {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"),
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else {
return super.viewForTop()
}
return molecule
}
override open func viewForBottom() -> UIView {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"),
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(forJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, constrainIfNeeded: true) else {
return viewForBottom()
}
return molecule
@ -38,31 +43,142 @@ open class MoleculeListTemplate: ThreeLayerTableViewController {
open override func newDataBuildScreen() {
super.newDataBuildScreen()
_ = setupMoleculeList()
registerWithTable()
}
open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
if let moleculeName = loadObject?.pageJSON?.stringOptionalWithChainOfKeysOrIndexes([KeyMolecules,indexPath.row,KeyMoleculeName]), let theClass = MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping?[moleculeName] as? MVMCoreUIMoleculeViewProtocol.Type,
let estimatedHeightForRow = theClass.estimatedHeightForRow {
return estimatedHeightForRow()
// MARK: - table
open override func registerWithTable() {
super.registerWithTable()
guard let molecules = molecules else {
return
}
return 0
for molecule in molecules {
if let moleculeInfo = getMoleculeInfo(with: molecule), let moleculeToRegister = moleculeInfo.name {
tableView?.register(moleculeInfo.class, forCellReuseIdentifier: moleculeToRegister)
}
}
}
open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
guard let molecule = molecules?[indexPath.row],
let moleculeInfo = getMoleculeInfo(with: molecule),
let estimatedHeight = moleculeInfo.class.estimatedHeight else {
return 0
}
return estimatedHeight(molecule.molecule)
}
open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return loadObject?.pageJSON?.arrayForKey(KeyMolecules).count ?? 0
return molecules?.count ?? 0
}
open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
guard let molecule = loadObject?.pageJSON?.optionalDictionaryWithChainOfKeysOrIndexes([KeyMolecules,indexPath.row]),
let moleculeName = molecule.optionalStringForKey(KeyMoleculeName),
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeName) as? MoleculeTableViewCell else {
guard let molecule = molecules?[indexPath.row],
let moleculeInfo = getMoleculeInfo(with: molecule),
let moleculeName = moleculeInfo.name,
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeName) else {
return UITableViewCell()
}
let delegate = delegateObject()
cell.setWithJSON(molecule, delegateObject: delegate, additionalData: nil)
cell.setSeparatorWithJSON(loadObject?.pageJSON?.optionalDictionaryForKey("separator"), delegateObject: delegate, additionalData: nil, indexPath: indexPath)
cell.updateView(tableView.bounds.width)
let delegate = delegateObject() as? MVMCoreUIDelegateObject
if let protocolCell = cell as? MoleculeListCellProtocol {
protocolCell.setSeparatorWithJSON?(loadObject?.pageJSON?.optionalDictionaryForKey("separator"), delegateObject: delegate, additionalData: nil, indexPath: indexPath)
}
if let protocolCell = cell as? MVMCoreUIMoleculeViewProtocol {
protocolCell.setWithJSON(molecule.molecule, delegateObject: delegate, additionalData: nil)
protocolCell.updateView(tableView.bounds.width)
}
return cell
}
open override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if let cell = tableView.cellForRow(at: indexPath) as? MoleculeListCellProtocol {
cell.didSelectCell?(atIndex: indexPath, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
}
}
// MARK: - cache handling
open override func pageTypesToListenFor() -> [Any]? {
guard let pageType = self.pageType else {
return super.pageTypesToListenFor()
}
return [pageType]
}
open override func modulesToListenFor() -> [Any]? {
// Get all of the molecules that need modules.
return modulesNeeded()
}
// MARK: - Module Molecule Handling
/// Returns the (name, class) of the molecule for the given map.
func getMoleculeInfo(with molecule: (molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)) -> (name: String?, class: AnyClass)? {
guard let map = molecule.molecule, let moleculeName = map.optionalStringForKey(KeyMoleculeName), let moleculeClass = MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping[moleculeName] as? AnyClass else {
return nil
}
if let moleculeClass = moleculeClass as? MoleculeListCellProtocol.Type, let moleculeNameFunc = moleculeClass.moleculeName {
return (moleculeNameFunc(map, delegateObject() as? MVMCoreUIDelegateObject), moleculeClass)
} else {
return (moleculeName, moleculeClass)
}
}
/// Sets up the molecule list and ensures no errors loading all content.
func setupMoleculeList() -> [MVMCoreErrorObject]? {
var errors: [MVMCoreErrorObject] = []
let delegate = delegateObject() as? MVMCoreUIDelegateObject
var moleculeList: [(molecule: [AnyHashable: Any]?, moduleName: String?, error: MVMCoreErrorObject?)] = []
if let molecules = loadObject?.pageJSON?.optionalArrayForKey(KeyMolecules) as? [[AnyHashable: Any]] {
for molecule in molecules {
if let object = MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: molecule, delegateObject: delegate) {
if let error = object.error {
errors.append(error)
} else {
moleculeList.append(object)
}
}
}
}
molecules = moleculeList
return errors.count > 0 ? errors : nil
}
/// Sets up the header, footer, molecule list and ensures no errors loading all content.
func setup() -> [MVMCoreErrorObject]? {
var errors: [MVMCoreErrorObject] = []
let delegate = delegateObject() as? MVMCoreUIDelegateObject
MoleculeListTemplate.addToErrorList(with: MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate), errors: &errors)
MoleculeListTemplate.addToErrorList(with: MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate), errors: &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]) {
if let error = moleculeObject?.error {
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 {
MoleculeListTemplate.addToModuleList(with: molecule, moduleNames: &modules)
}
}
return (modules.count > 0 ? modules : nil)
}
}

View File

@ -8,27 +8,8 @@
import UIKit
public class MoleculeStackCenteredTemplate: ThreeLayerViewController {
public override func viewForMiddle() -> UIView? {
let molecule = loadObject?.pageJSON?.optionalDictionaryForKey("moleculeStack")
let moleculeStack = MoleculeStackView(withJSON: molecule, delegateObject: delegateObject(), additionalData: nil)
return moleculeStack
}
public override func viewForTop() -> UIView? {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"),
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else {
return nil
}
return molecule
}
override public func viewForBottom() -> UIView? {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"),
let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else {
return nil
}
return molecule
public class MoleculeStackCenteredTemplate: MoleculeStackTemplate {
public override func spaceBetweenTopAndMiddle() -> CGFloat? {
return nil
}
}

View File

@ -10,13 +10,22 @@ import UIKit
public class MoleculeStackTemplate: ThreeLayerViewController {
public override func shouldFinishProcessingLoad(_ loadObject: MVMCoreLoadObject, error: AutoreleasingUnsafeMutablePointer<MVMCoreErrorObject>) -> Bool {
var shouldFinish = super.shouldFinishProcessingLoad(loadObject, error: error)
if shouldFinish, let firstError = modulesNeeded().errors?.first {
// Don't continue if there was an error loading needed modules.
error.pointee = firstError
shouldFinish = false
}
return shouldFinish
}
public override func spaceBetweenTopAndMiddle() -> CGFloat? {
return 0
}
public override func viewForTop() -> UIView? {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) 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 molecule
@ -26,13 +35,42 @@ public class MoleculeStackTemplate: ThreeLayerViewController {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("moleculeStack") else {
return nil
}
return MoleculeStackView(withJSON: moleculeJSON, delegateObject: delegateObject(), additionalData: nil)
return MoleculeStackView(withJSON: moleculeJSON, delegateObject: delegateObject() as? MVMCoreUIDelegateObject, additionalData: nil)
}
override public func viewForBottom() -> UIView? {
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) 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 molecule
}
// MARK: - cache handling
public override func pageTypesToListenFor() -> [Any]? {
guard let pageType = self.pageType else {
return super.pageTypesToListenFor()
}
return [pageType]
}
public override func modulesToListenFor() -> [Any]? {
// Get all of the molecules that need modules.
return modulesNeeded().modules
}
// MARK: - Module Molecule Handling
func modulesNeeded() -> (modules: [String]?, errors: [MVMCoreErrorObject]?) {
var modules: [String]? = []
var errors: [MVMCoreErrorObject]? = []
let delegate = delegateObject() as? MVMCoreUIDelegateObject
let _ = MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("header"), delegateObject: delegate, moduleNames: &modules, errors: &errors)
let _ = MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: loadObject?.pageJSON?.optionalDictionaryForKey("footer"), delegateObject: delegate, moduleNames: &modules, errors: &errors)
if let molecules = loadObject?.pageJSON?.optionalArrayForChainOfKeysOrIndexes(["moleculeStack",KeyMolecules]) as? [[AnyHashable: Any]] {
for molecule in molecules {
let _ = MVMCoreUIMoleculeMappingObject.getMoleculeJSON(for: molecule, delegateObject: delegate, moduleNames: &modules, errors: &errors)
}
}
return (modules?.count ?? 0 > 0 ? modules : nil, errors?.count ?? 0 > 0 ? errors : nil)
}
}

View File

@ -15,6 +15,7 @@ extern NSString * const KeyScreenHeading;
extern NSString * const KeyMolecules;
extern NSString * const KeyMoleculeName;
extern NSString * const KeyMolecule;
extern NSString * const KeyDisableButton;
@ -68,3 +69,11 @@ extern BOOL DisableAnimations;
// Hand Scroll Key
extern NSString * const KeyHandScrollAnimation;
extern NSString * const KeyHandScroll;
#pragma mark - Error Codes
// Native Error Codes (Add new ones to bottom, don't change order!)
typedef NS_ENUM(NSInteger, CoreUIErrorCode) {
ErrorCodeModuleMolecule = 100,
ErrorCodeListMolecule = 101
};

View File

@ -14,6 +14,7 @@ NSString * const KeyScreenHeading = @"screenHeading";
NSString * const KeyMolecules = @"molecules";
NSString * const KeyMoleculeName = @"moleculeName";
NSString * const KeyMolecule = @"molecule";
NSString * const KeyDisableButton = @"disableAction";