From abe80a1ce31f4d61cbd9a8c354d41fbd03d0799c Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Fri, 29 Mar 2019 10:00:35 -0400 Subject: [PATCH 01/27] Converted LabelWithInternalButton.h/m to LabelWithInternalButton.swift. Removed LabelWithInternalButton.h/m. Changes reflected in project file. --- MVMCoreUI.xcodeproj/project.pbxproj | 12 +- .../Atoms/Views/LabelWithInternalButton.h | 94 --- .../Atoms/Views/LabelWithInternalButton.m | 557 --------------- .../Atoms/Views/LabelWithInternalButton.swift | 647 ++++++++++++++++++ MVMCoreUI/MVMCoreUI.h | 1 - 5 files changed, 651 insertions(+), 660 deletions(-) delete mode 100644 MVMCoreUI/Atoms/Views/LabelWithInternalButton.h delete mode 100644 MVMCoreUI/Atoms/Views/LabelWithInternalButton.m create mode 100644 MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 40733e65..2cd04862 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -150,11 +150,10 @@ D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; }; D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */; }; - D2C5001D21F8EE67001DA659 /* LabelWithInternalButton.h in Headers */ = {isa = PBXBuildFile; fileRef = D2C5001B21F8EE66001DA659 /* LabelWithInternalButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D2C5001E21F8EE67001DA659 /* LabelWithInternalButton.m in Sources */ = {isa = PBXBuildFile; fileRef = D2C5001C21F8EE66001DA659 /* LabelWithInternalButton.m */; }; DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; }; DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; }; DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretButton.swift */; }; + DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */; }; /* End PBXBuildFile section */ /* Begin PBXFileReference section */ @@ -305,11 +304,10 @@ D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerViewController.swift; sourceTree = ""; }; D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewControllerMappingObject.h; sourceTree = ""; }; D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIViewControllerMappingObject.m; sourceTree = ""; }; - D2C5001B21F8EE66001DA659 /* LabelWithInternalButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelWithInternalButton.h; sourceTree = ""; }; - D2C5001C21F8EE66001DA659 /* LabelWithInternalButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LabelWithInternalButton.m; sourceTree = ""; }; DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = ""; }; DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = ""; }; DBC4391A224421A0001AB423 /* CaretButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretButton.swift; sourceTree = ""; }; + DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelWithInternalButton.swift; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -543,8 +541,6 @@ D29DF28621E7AC2B003B2FB9 /* MFLabel.m */, D29DF31E21ED0CBA003B2FB9 /* LabelView.h */, D29DF31F21ED0CBA003B2FB9 /* LabelView.m */, - D2C5001B21F8EE66001DA659 /* LabelWithInternalButton.h */, - D2C5001C21F8EE66001DA659 /* LabelWithInternalButton.m */, D29DF28721E7AC2B003B2FB9 /* ViewConstrainingView.h */, D29DF28821E7AC2B003B2FB9 /* ViewConstrainingView.m */, D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */, @@ -566,6 +562,7 @@ D22D1F19220341F50077CEC0 /* MVMCoreUICheckBox.m */, D22D1F44220496A30077CEC0 /* MVMCoreUISwitch.h */, D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */, + DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */, ); path = Views; sourceTree = ""; @@ -725,7 +722,6 @@ D29DF17521E69E1F003B2FB9 /* ButtonDelegateProtocol.h in Headers */, D29DF18221E69E54003B2FB9 /* SeparatorView.h in Headers */, D29DF26E21E6AA0B003B2FB9 /* FLAnimatedImage.h in Headers */, - D2C5001D21F8EE67001DA659 /* LabelWithInternalButton.h in Headers */, D29DF11621E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.h in Headers */, D29DF17721E69E1F003B2FB9 /* MFTextButton.h in Headers */, D29DF16221E69996003B2FB9 /* MFViewController.h in Headers */, @@ -845,6 +841,7 @@ D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */, D29DF25321E6A177003B2FB9 /* MFDigitTextField.m in Sources */, D29DF12F21E6851E003B2FB9 /* MVMCoreUITopAlertMainView.m in Sources */, + DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */, D29DF17C21E69E1F003B2FB9 /* MFTextButton.m in Sources */, D29DF2C521E7BF57003B2FB9 /* MFTabBarSwipeAnimator.m in Sources */, D29DF2B421E7B76D003B2FB9 /* MFLoadingSpinner.m in Sources */, @@ -897,7 +894,6 @@ D29DF25121E6A177003B2FB9 /* MFDigitTextBox.m in Sources */, DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, - D2C5001E21F8EE67001DA659 /* LabelWithInternalButton.m in Sources */, D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */, D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */, D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.h b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.h deleted file mode 100644 index 10c0bfdd..00000000 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.h +++ /dev/null @@ -1,94 +0,0 @@ -// -// TextMixedWithButtonView.h -// mobilefirst -// -// Created by Chris Yang on 2/25/16. -// Copyright © 2016 Verizon Wireless. All rights reserved. -// - -#import -#import -#import -#import -#import -#import - -typedef void (^ActionBlock)(void); - -@interface LabelWithInternalButton : UIControl - -@property (nullable, copy, nonatomic) ActionBlock actionBlock; -@property (nullable, weak, nonatomic) MFLabel *label; - -@property (nullable, strong, nonatomic) NSString *frontText; -@property (nullable, strong, nonatomic) NSString *actionText; -@property (nullable, strong, nonatomic) NSString *backText; -@property (nullable, strong, nonatomic) NSAttributedString *attributedText; - -//by default, it will follow most of the font standard in zepplin, and should need to be changed -@property (nullable, strong, nonatomic) UIFont *normalTextFont; -@property (nullable, strong, nonatomic) UIFont *actionTextFont; -@property (nullable, strong, nonatomic) UIColor *normalTextColor; -@property (nullable, strong, nonatomic) UIColor *actionTextColor; - -@property (nullable, strong, nonatomic) NSString *alternateAttributeForActionText; - -@property (assign, nonatomic) BOOL makeWholeViewClickable; - -// with button delegate -- (nullable instancetype)initWithActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate; -- (nullable instancetype)initWithFrontText:(nullable NSString *)frontText backText:(nullable NSString *)backText actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate; -- (nullable instancetype)initWithFrontText:(nullable NSString *)frontText actionText:(nullable NSString *)actionText backText:(nullable NSString *)backText actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate; -// set with button delegate -- (void)setActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate; -- (void)setFrontText:(nullable NSString *)frontText actionMap:(nullable NSDictionary *)actionMap backText:(nullable NSString *)backText additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate; -- (void)setFrontAttributedText:(nullable NSAttributedString *)frontAttributedText actionMap:(nullable NSDictionary *)actionMap backAttributedText:(nullable NSAttributedString *)backText additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate; -- (void)setFrontAttributedText:(nullable NSAttributedString *)frontAttributedText actionMap:(nullable NSDictionary *)actionMap backAttributedText:(nullable NSAttributedString *)backAttributedText addNewLine:(BOOL) addNewLine additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate; - - -// legacy -- (nullable instancetype)initWithFrontText:(nullable NSString *)frontText actionText:(nullable NSString *)actionText backText:(nullable NSString *)backText actionBlock:(nullable ActionBlock)block; -- (nullable instancetype)initWithFrontText:(nullable NSString *)frontText actionText:(nullable NSString *)actionText backText:(nullable NSString *)backText actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate; - -- (nullable instancetype)initWithActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate; - -//this assume that the action text is the "title" key in action map -- (nullable instancetype)initWithFrontText:(nullable NSString *)frontText backText:(nullable NSString *)backText actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate; - -// Convenience Initializer which assumes that the clickable text will be embedded in curly braces {}. -- (nullable instancetype)initWithClickableTextEmbeddedInCurlyBraces:(nullable NSString *)fullText actionMapForClickableText:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate; -// Convenience Initializer which assumes that the clickable text will be embedded in any tag. -- (nullable instancetype)initWithText:(nullable NSString *)fullText startTag:(nullable NSString *)startTag endTag:(nullable NSString *)endTag actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate; - - -//set action map -- (void)setActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate; - -//set text with curly braces -- (void)setCurlyBracedText:(nonnull NSString *)text; -// set text with any tags -- (void)setWithText:(nullable NSString *)fullText startTag:(nullable NSString *)startTag endTag:(nullable NSString *)endTag actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate; - -// Reset the text, action map and delegate -- (void)setTextWithClickableTextEmbeddedInCurlyBraces:(nullable NSString *)text textAttributes:(nullable NSDictionary *)attributes actionMapForClickableText:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate; - -// Reset the front text, back text, action map -- (void)setFrontText:(nullable NSString *)frontText actionMap:(nullable NSDictionary *)actionMap backText:(nullable NSString *)backText additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate; - -// Reset the front text, back text, action map -- (void)setFrontAttributedText:(nullable NSAttributedString *)frontAttributedText actionMap:(nullable NSDictionary *)actionMap backAttributedText:(nullable NSAttributedString *)backText additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate; -- (void)setFrontAttributedText:(nullable NSAttributedString *)frontAttributedText actionMap:(nullable NSDictionary *)actionMap backAttributedText:(nullable NSAttributedString *)backAttributedText addNewLine:(BOOL) addNewLine additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate; - -- (void)resetWithActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary * )additionalData delegate:(nullable NSObject *)delegate; - -- (void)setAlignment:(NSTextAlignment)textAlignment; - -- (void)setEnabled:(BOOL)enabled; - -- (void)setAlternateActionTextAttributes:(nullable NSDictionary *)attributes; - -- (void)setActionTextString:(nullable NSString *)actionText; - -- (nonnull UIAccessibilityCustomAction *)accessibilityCustomAction; - -@end diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.m b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.m deleted file mode 100644 index c4c509c5..00000000 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.m +++ /dev/null @@ -1,557 +0,0 @@ -// -// TextMixedWithButtonView.m -// mobilefirst -// -// Created by Chris Yang on 2/25/16. -// Copyright © 2016 Verizon Wireless. All rights reserved. -// - -#import "LabelWithInternalButton.h" -#import -#import -#import -#import -#import -#import -#import -#import -#import - -@interface LabelWithInternalButton () - -@property (nullable, strong, nonatomic) NSString *text; - -@end - -@implementation LabelWithInternalButton - - - -- (nullable instancetype)initWithActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate { - return [self initWithFrontText:[actionMap stringForKey:KeyTitlePrefix] actionText:[actionMap stringForKey:KeyTitle] backText:[actionMap stringForKey:KeyTitlePostfix] actionMap:actionMap additionalData:additionalData actionDelegate:delegate buttonDelegate:buttonDelegate]; -} - -- (nullable instancetype)initWithFrontText:(nullable NSString *)frontText backText:(nullable NSString *)backText actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate { - return [self initWithFrontText:frontText actionText:[actionMap stringForKey:KeyTitle] backText:backText actionMap:actionMap additionalData:additionalData actionDelegate:delegate buttonDelegate:buttonDelegate]; -} - -- (nullable instancetype)initWithFrontText:(nullable NSString *)frontText actionText:(nullable NSString *)actionText backText:(nullable NSString *)backText actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate { - if (self = [super init]) { - [self setFrontText:frontText actionText:actionText actionMap:actionMap backText:backText additionalData:additionalData delegate:delegate buttonDelegate:buttonDelegate]; - } - return self; -} - -- (void)setActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate { - __weak typeof(self) weakSelf = self; - __weak typeof(delegate) weakDelegate = delegate; - __weak typeof(buttonDelegate) weakButtonDelegate = buttonDelegate; - self.actionBlock = ^{ - BOOL performAction = YES; - if (weakButtonDelegate && [weakButtonDelegate respondsToSelector:@selector(button:shouldPerformActionWithMap:additionalData:)]) { - performAction = [weakButtonDelegate button:weakSelf shouldPerformActionWithMap:actionMap additionalData:additionalData]; - } - - if (performAction) { - [[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:actionMap additionalData:additionalData delegate:weakDelegate]; - } - }; -} - -- (void)setFrontText:(NSString *)frontText actionMap:(NSDictionary *)actionMap backText:(NSString *)backText additionalData:(NSDictionary *)additionalData delegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate { - [self setFrontText:frontText actionText:[actionMap stringForKey:KeyTitle] actionMap:actionMap backText:backText additionalData:additionalData delegate:delegate buttonDelegate:buttonDelegate]; -} - -- (void)setFrontText:(NSString *)frontText actionText:(NSString *)actionText actionMap:(NSDictionary *)actionMap backText:(NSString *)backText additionalData:(NSDictionary *)additionalData delegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate { - self.frontText = frontText; - [self setActionMap:actionMap additionalData:additionalData actionDelegate:delegate buttonDelegate:buttonDelegate]; - self.actionText = actionText; - self.backText = backText; - self.text = [self getTextFromStringComponents]; - [self setup]; -} - -- (void)setFrontAttributedText:(nullable NSAttributedString *)frontAttributedText actionMap:(nullable NSDictionary *)actionMap backAttributedText:(nullable NSAttributedString *)backText additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate { - [self setFrontAttributedText:frontAttributedText actionMap:actionMap backAttributedText:backText addNewLine:NO additionalData:additionalData delegate:delegate buttonDelegate:buttonDelegate]; -} - -- (void)setFrontAttributedText:(nullable NSAttributedString *)frontAttributedText actionMap:(nullable NSDictionary *)actionMap backAttributedText:(nullable NSAttributedString *)backAttributedText addNewLine:(BOOL) addNewLine additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate buttonDelegate:(nullable NSObject *)buttonDelegate { - NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] init]; - if (frontAttributedText) { - [attributedString appendAttributedString:frontAttributedText]; - // need to do this to fix the range issue - self.frontText = frontAttributedText.string; - } - - NSString *newLineAttributed = [[NSString alloc] initWithString:addNewLine?@"\n":@" "]; - - if (actionMap.allKeys.count > 0) { - - NSMutableString *actionString = [[actionMap stringForKey:KeyTitle] mutableCopy]; - - if (actionString.length > 0) { - - [actionString appendString:newLineAttributed]; - - NSAttributedString *actionAttributedString = [MFStyler styleGetAttributedString:actionString font:[MFStyler fontB2] color:[UIColor blackColor]]; - - self.actionText = actionString; - [self setActionMap:actionMap additionalData:additionalData actionDelegate:delegate buttonDelegate:buttonDelegate]; - - [attributedString appendAttributedString:actionAttributedString]; - } - } else { - self.actionText = nil; - self.actionBlock = nil; - } - - if (backAttributedText) { - [attributedString appendAttributedString:backAttributedText]; - } - self.attributedText = attributedString; - - //added this line for underlining - [self setAlternateActionTextAttributes:@{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)}]; -} - -#pragma mark - legacy - -- (nullable instancetype)initWithFrontText:(nullable NSString *)frontText actionText:(nullable NSString *)actionText backText:(nullable NSString *)backText actionBlock:(nullable ActionBlock)block { - if (self = [super init]) { - self.frontText = frontText; - self.actionText = actionText; - self.backText = backText; - self.actionBlock = block; - self.text = [self getTextFromStringComponents]; - [self setup]; - } - return self; -} -- (nullable instancetype)initWithFrontText:(nullable NSString *)frontText actionText:(nullable NSString *)actionText backText:(nullable NSString *)backText actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate { - return [self initWithFrontText:frontText actionText:actionText backText:backText actionMap:actionMap additionalData:additionalData actionDelegate:delegate buttonDelegate:nil]; -} - -- (nullable instancetype)initWithActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate { - return [self initWithFrontText:[actionMap stringForKey:KeyTitlePrefix] actionText:[actionMap stringForKey:KeyTitle] backText:[actionMap stringForKey:KeyTitlePostfix] actionMap:actionMap additionalData:additionalData actionDelegate:delegate]; -} - -- (instancetype)init -{ - self = [super init]; - if (self) { - [self setup]; - } - return self; -} - - -- (instancetype)initWithCoder:(NSCoder *)coder -{ - self = [super initWithCoder:coder]; - if (self) { - [self setup]; - } - return self; -} - -- (instancetype)initWithFrame:(CGRect)frame -{ - self = [super initWithFrame:frame]; - if (self) { - [self setup]; - } - return self; -} - -- (nullable instancetype)initWithFrontText:(nullable NSString *)frontText backText:(nullable NSString *)backText actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate { - return [self initWithFrontText:frontText actionText:[actionMap stringForKey:KeyTitle] backText:backText actionMap:actionMap additionalData:additionalData actionDelegate:delegate]; -} - -// Convenience Initializer which assumes that the clickable text will be embedded in curly braces {}. -- (nullable instancetype)initWithClickableTextEmbeddedInCurlyBraces:(nullable NSString *)fullText actionMapForClickableText:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate { - return [self initWithText:fullText startTag:@"{" endTag:@"}" actionMap:actionMap additionalData:additionalData actionDelegate:delegate]; -} - -- (instancetype)initWithText:(nullable NSString *)fullText startTag:(nullable NSString *)startTag endTag:(nullable NSString *)endTag actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate -{ - self = [super init]; - if (self) { - [self setText:fullText startTag:startTag endTag:endTag]; - __weak typeof(delegate) weakDelegate = delegate; - self.actionBlock = ^{ - [[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:actionMap additionalData:additionalData delegate:weakDelegate]; - }; - } - return self; -} - -- (void)setup { - if (!self.label) { - MFLabel *label = [[MFLabel alloc] initWithFrame:CGRectZero]; - - self.backgroundColor = [UIColor clearColor]; - label.translatesAutoresizingMaskIntoConstraints = NO; - label.userInteractionEnabled = NO; - label.numberOfLines = 0; - label.lineBreakMode = NSLineBreakByWordWrapping; - [label setContentCompressionResistancePriority:UILayoutPriorityRequired forAxis:UILayoutConstraintAxisVertical]; - [self addSubview:label]; - [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[label]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(label)]]; - [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0-[label]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(label)]]; - - - self.label = label; - [label sizeToFit]; - } - - if (!self.normalTextColor) { - self.normalTextColor = [UIColor blackColor]; - } - if (!self.actionTextColor) { - self.actionTextColor = [UIColor blackColor]; - } - if (!self.normalTextFont) { - self.normalTextFont = [MFStyler fontB2]; - } - if (!self.actionTextFont) { - self.actionTextFont = [MFStyler fontB2]; - } - - //adding the underline - [self setAlternateActionTextAttributes:@{NSUnderlineStyleAttributeName: @(NSUnderlineStyleSingle)}]; - - self.label.attributedText = self.attributedText; - [self.label setAccessibilityTraits:UIAccessibilityTraitButton]; -} - -- (void)updateView:(CGFloat)size { - //reset font for app size change - self.normalTextFont = [MFStyler fontB2]; - self.actionTextFont = [MFStyler fontB2]; - self.label.attributedText = self.attributedText; -} - -#pragma mark - UIControl overide - -- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { - if ([self areTouchesInActionString:touches]) { - [self sendActionsForControlEvents:UIControlEventTouchUpInside]; - [self performAction]; - } else { - [self sendActionsForControlEvents:UIControlEventTouchUpOutside]; - } -} - -#pragma mark - helper - -- (NSString *)getTextFromStringComponents { - if (self.frontText.length == 0) { - self.frontText = @""; - } else { - self.frontText = [self.frontText stringByAppendingString:[self spaceBetweenPartOne:self.frontText andPartTwo:self.actionText]]; - } - if (self.actionText.length == 0) { - self.actionText = @""; - } else { - self.actionText = [self.actionText stringByAppendingString:[self spaceBetweenPartOne:self.actionText andPartTwo:self.backText]]; - } - if (self.backText.length == 0) { - self.backText = @""; - } - return [[NSString alloc] initWithFormat:@"%@%@%@",self.frontText, self.actionText, self.backText]; -} - -- (NSString *)spaceBetweenPartOne:(NSString *)partOne andPartTwo:(NSString *)partTwo { - /*if (!partTwo || partTwo.length == 0 || [MFUtility validateString:partTwo withRegularExpression:@"[.,?!;:]"] || [partOne hasSuffix:@" "]) { - return @""; - }*/ - return @" "; -} - -- (NSRange)getActionRange { - return NSMakeRange(self.frontText.length, self.actionText.length); -} - -- (NSRange)getFrontRange { - return NSMakeRange(0, self.frontText.length); -} - -- (NSRange)getBackRange { - return NSMakeRange(self.frontText.length + self.actionText.length, self.backText.length);} - -- (void)performAction { - if (self.actionBlock) { - self.actionBlock(); - } -} - -- (NSArray *)getRangeArrayOfWordsInString:(NSString *)string withInitalIndex:(NSInteger)index { - NSArray *words = [string componentsSeparatedByString:@" "]; - NSMutableArray *rangeArray = [[NSMutableArray alloc] init]; - for (NSString *subString in words) { - NSString *finalSubString = [subString stringByAppendingString:@" "]; - NSInteger wordIndex = index; - NSInteger length = finalSubString.length; - NSRange subStringRange = NSMakeRange(wordIndex, length); - NSValue *rangeValue = [NSValue valueWithRange:subStringRange]; - [rangeArray addObject:rangeValue]; - index += length; - } - return rangeArray; -} - -- (NSArray *)getRectArrayFromRangeArray:(NSArray *)rangeArray { - NSMutableArray *rectArray = [[NSMutableArray alloc] init]; - for (NSValue *aValueOfRange in rangeArray) { - NSRange wordRange = [aValueOfRange rangeValue]; - CGRect rect = [self.label boundingRectForCharacterRange:wordRange]; - NSValue *rectValue = [NSValue valueWithCGRect:rect]; - [rectArray addObject:rectValue]; - } - return rectArray; -} - -- (BOOL)areTouchesInActionString:(NSSet *)touches { - if (UIAccessibilityIsVoiceOverRunning() || self.makeWholeViewClickable) { - return YES; - } - CGPoint location = [[touches anyObject] locationInView:self.label]; - NSString *actionString = self.actionText; - NSInteger index = [self getActionRange].location; - NSArray *rangeArray = [self getRangeArrayOfWordsInString:actionString withInitalIndex:index]; - NSArray *rectArray = [self getRectArrayFromRangeArray:rangeArray]; - BOOL result = NO; - for (NSValue *aValueOfRect in rectArray) { - CGRect wordRect = [aValueOfRect CGRectValue]; - if (CGRectContainsPoint(wordRect, location)){ - result = YES; - break; - } else if (wordRect.origin.x == 0 && wordRect.origin.y == 0 && wordRect.size.height == 0 && wordRect.size.width == 0) { - //incase word rect is not found for any reason, make the whole label to be clicable to avoid non functioning link in production. - result = YES; - break; - } - } - return result; -} - - -#pragma mark - setter - -- (void)setText:(NSString *)text { - if (text) { - _text = text; - - self.attributedText = [[NSAttributedString alloc] initWithString:text]; - //call the setters to properly set the attributes - [self setNormalTextFont:self.normalTextFont]; - [self setActionTextFont:self.actionTextFont]; - [self setNormalTextColor:self.normalTextColor]; - [self setActionTextColor:self.actionTextColor]; - - } -} - - -- (void)setCurlyBracedText:(nonnull NSString *)text { - [self setText:text startTag:@"{" endTag:@"}"]; -} - -- (void)setText:(NSString *)text startTag:(NSString *)startTag endTag:(NSString *)endTag { - NSRange actionRange = [self rangeOfText:&text startTag:startTag endTag:endTag]; - self.frontText = [text substringWithRange:NSMakeRange(0,actionRange.location)]; - self.actionText = [text substringWithRange:actionRange]; - self.backText = [text substringWithRange:NSMakeRange(self.frontText.length+self.actionText.length, text.length - self.frontText.length-self.actionText.length)]; - self.text = [self getTextFromStringComponents]; - [self setup]; -} - -- (NSRange)rangeOfCurlyBracedText:(NSString **)text { - return [self rangeOfText:text startTag:@"{" endTag:@"}"]; -} - -- (NSRange)rangeOfText:(NSString **)text startTag:(NSString *)startTag endTag:(NSString *)endTag { - - NSString *fullText = *text; - NSRange range = NSMakeRange(0, 0); - NSRange rangeOfLeftBrace = [fullText rangeOfString:startTag]; - - if (rangeOfLeftBrace.location != NSNotFound) { - - fullText = [fullText stringByReplacingCharactersInRange:rangeOfLeftBrace withString:@""]; - NSRange rangeOfRightBrace = [fullText rangeOfString:endTag]; - - if (rangeOfRightBrace.location != NSNotFound) { - - NSInteger length = (rangeOfRightBrace.location - rangeOfLeftBrace.location); - - if (length > 0) { - range = NSMakeRange(rangeOfLeftBrace.location, length); - fullText = [fullText stringByReplacingCharactersInRange:rangeOfRightBrace withString:@""]; - } - } - } - *text = fullText; - - return range; -} - -- (void)setNormalTextColor:(UIColor *)normalTextColor { - if (normalTextColor) { - _normalTextColor = normalTextColor; - [self setAlternateNormalTextAttributes:@{NSForegroundColorAttributeName:normalTextColor}]; - } -} - -- (void)setActionTextColor:(UIColor *)actionTextColor { - if (actionTextColor) { - _actionTextColor = actionTextColor; - [self setAlternateActionTextAttributes:@{NSForegroundColorAttributeName:actionTextColor}]; - } -} - -- (void)setAttributedText:(NSAttributedString *)attributedText { - _attributedText = attributedText; - NSMutableAttributedString *mutableAttributedText = [attributedText mutableCopy]; - NSMutableParagraphStyle *paragraphStyle = [[NSMutableParagraphStyle alloc] init]; - paragraphStyle.lineSpacing = LabelWithInternalButtonLineSpace; - [mutableAttributedText addAttribute:NSParagraphStyleAttributeName value:paragraphStyle range:NSMakeRange(0, attributedText.length)]; - - if (self.label && mutableAttributedText) { - self.label.attributedText = mutableAttributedText; - } - -} - -- (void)setNormalTextFont:(UIFont *)normalTextFont { - if (normalTextFont) { - _normalTextFont = normalTextFont; - [self setAlternateNormalTextAttributes:@{NSFontAttributeName:normalTextFont}]; - } -} - -- (void)setActionTextFont:(UIFont *)actionTextFont { - if (actionTextFont) { - _actionTextFont = actionTextFont; - [self setAlternateActionTextAttributes:@{NSFontAttributeName:actionTextFont}]; - } -} - -- (void)setActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate { - [self setActionMap:actionMap additionalData:additionalData actionDelegate:delegate buttonDelegate:nil]; -} - -// Reset the text and action map -- (void)setTextWithClickableTextEmbeddedInCurlyBraces:(nullable NSString *)text textAttributes:(nullable NSDictionary *)attributes actionMapForClickableText:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate { - - self.attributedText = [[NSAttributedString alloc] initWithString:text attributes:attributes]; - [self setActionMap:actionMap additionalData:additionalData actionDelegate:delegate]; -} - -- (void)setWithText:(nullable NSString *)fullText startTag:(nullable NSString *)startTag endTag:(nullable NSString *)endTag actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject *)delegate { - [self setText:fullText startTag:startTag endTag:endTag]; - [self setActionMap:actionMap additionalData:additionalData actionDelegate:delegate]; -} - -- (void)setEnabled:(BOOL)enabled { - [super setEnabled:enabled]; - if (enabled) { - self.alpha = 1; - } else { - self.alpha = DisableOppacity; - } -} - -- (void)setFrontText:(NSString *)frontText actionMap:(NSDictionary *)actionMap backText:(NSString *)backText additionalData:(NSDictionary *)additionalData delegate:(nullable NSObject *)delegate { - [self setFrontText:frontText actionMap:actionMap backText:backText additionalData:additionalData delegate:delegate buttonDelegate:nil]; -} - -// Reset the front text, back text, action map -- (void)setFrontAttributedText:(nullable NSAttributedString *)frontAttributedText actionMap:(nullable NSDictionary *)actionMap backAttributedText:(nullable NSAttributedString *)backAttributedText additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate { - [self setFrontAttributedText:frontAttributedText actionMap:actionMap backAttributedText:backAttributedText addNewLine:NO additionalData:additionalData delegate:delegate]; -} - -- (void)setFrontAttributedText:(nullable NSAttributedString *)frontAttributedText actionMap:(nullable NSDictionary *)actionMap backAttributedText:(nullable NSAttributedString *)backAttributedText addNewLine:(BOOL) addNewLine additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject *)delegate { - - [self setFrontAttributedText:frontAttributedText actionMap:actionMap backAttributedText:backAttributedText addNewLine:addNewLine additionalData:additionalData delegate:delegate buttonDelegate:nil]; -} - -- (void)setAlignment:(NSTextAlignment)textAlignment { - self.label.textAlignment = textAlignment; -} - -- (void)setAlternateActionTextAttributes:(nullable NSDictionary *)attributes { - if (attributes) { - NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText]; - [attributedString addAttributes:attributes range:[self getActionRange]]; - self.attributedText = attributedString; - } -} - -- (void)setAlternateNormalTextAttributes:(nullable NSDictionary *)attributes { - if (attributes) { - NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.attributedText]; - [attributedString addAttributes:attributes range:[self getFrontRange]]; - [attributedString addAttributes:attributes range:[self getBackRange]]; - - self.attributedText = attributedString; - } -} - -- (void)setActionTextString:(nullable NSString *)actionText { - self.actionText = actionText; - self.text = [self getTextFromStringComponents]; - [self setup]; -} - -/// Used to just reset the texts and actions if already initialized -- (void)resetWithActionMap:(NSDictionary *)actionMap additionalData:(NSDictionary *)additionalData delegate:(NSObject *)delegate { - - self.frontText = [actionMap stringForKey:KeyTitlePrefix]; - self.actionText = [actionMap stringForKey:KeyTitle]; - self.backText = [actionMap stringForKey:KeyTitlePostfix]; - - - __weak typeof(delegate) weakDelegate = delegate; - self.actionBlock = ^{ - [[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:actionMap additionalData:additionalData delegate:weakDelegate]; - }; - - self.text = [self getTextFromStringComponents]; - [self setup]; -} - -//#pragma mark - Accessibility -// -//-(BOOL)isAccessibilityElement{ -// return YES; -//} -// -//-(UIAccessibilityTraits)accessibilityTraits{ -// return UIAccessibilityTraitLink; -//} - -- (NSString *)replaceSpaceWithFakeSpace:(NSString *)string { - NSArray *words = [string componentsSeparatedByString:@" "]; - return [words componentsJoinedByString:@"\u00a0"]; -} -- (BOOL)accessibilityActivate { - if (self.actionBlock) { - self.actionBlock(); - return YES; - } else { - return NO; - } - -} - -- (UIAccessibilityCustomAction *)accessibilityCustomAction { - if (self.actionText.length) { - NSString *name = self.actionText; - return [[UIAccessibilityCustomAction alloc] initWithName:name target:self selector:@selector(accessibilityActivate)]; - } else { - return [[UIAccessibilityCustomAction alloc] init]; - } - -} -@end diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift new file mode 100644 index 00000000..c87f0c54 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -0,0 +1,647 @@ +// +// LabelWithInternalButton.swift +// MVMCoreUI +// +// Created by Chris Yang on 2/25/16. +// Converted by Christiano, Kevin on 3/22/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import MVMCore + +public typealias ActionBlock = () -> Void +public typealias ActionObjectDelegate = (NSObject & MVMCoreActionDelegateProtocol) +public typealias ButtonObjectDelegate = (NSObject & ButtonDelegateProtocol) +public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProtocol & MVMCoreLoadDelegateProtocol & MVMCorePresentationDelegateProtocol & NSObjectProtocol + + +@objcMembers open class LabelWithInternalButton: UIControl, MVMCoreViewProtocol, MFButtonProtocol { + //------------------------------------------------------ + // MARK: - Properties + //------------------------------------------------------ + + public var actionBlock: ActionBlock? + public weak var label: MFLabel? + + public var alternateAttributeForActionText: String? + + public var attributedText: NSAttributedString? { + didSet(newAttributedText) { + if newAttributedText != nil { + let mutableAttributedText = newAttributedText as? NSMutableAttributedString + let paragraphStyle = NSMutableParagraphStyle() + paragraphStyle.lineSpacing = CGFloat(LabelWithInternalButtonLineSpace) + mutableAttributedText?.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttributedText?.length ?? 0)) + + if let mutableAttText = mutableAttributedText { + label?.attributedText = mutableAttText + } + } + } + } + + // By default, it will follow most of the font standard in zepplin, and should need to be changed + public var normalTextFont: UIFont? + public var actionTextFont: UIFont? + public var normalTextColor: UIColor? + public var actionTextColor: UIColor? + + public var makeWholeViewClickable = false + + override open var isEnabled: Bool { + didSet { + alpha = isEnabled ? 1 : DisableOppacity + } + } + + public var frontText: String? + public var actionText: String? + public var backText: String? + + public var text: String? { + didSet(newText) { + if newText != nil { + attributedText = NSAttributedString(string: newText ?? "") + setAlternateNormalTextAttributes([NSAttributedString.Key.font: normalTextFont as Any]) + setAlternateActionTextAttributes([NSAttributedString.Key.font: actionTextFont as Any]) + setAlternateNormalTextAttributes([NSAttributedString.Key.foregroundColor: normalTextColor as Any]) + setAlternateActionTextAttributes([NSAttributedString.Key.foregroundColor: actionTextColor as Any]) + } + } + } + + //------------------------------------------------------ + // MARK: - Initializaers + //------------------------------------------------------ + + public init() { + super.init(frame: CGRect.zero) + setup() + } + + required public init?(coder: NSCoder) { + super.init(coder: coder) + setup() + } + + override public init(frame: CGRect) { + super.init(frame: frame) + setup() + } + + public init(frontText: String?, + actionText: String?, + backText: String?, + actionMap: [AnyHashable: Any]?, + additionalData: [AnyHashable: Any]?, + actionDelegate delegate: ActionObjectDelegate?, + buttonDelegate: ButtonObjectDelegate?) { + + super.init(frame: CGRect.zero) + setFrontText(frontText, actionText: actionText, actionMap: actionMap, backText: backText, additionalData: additionalData, delegate: delegate, buttonDelegate: buttonDelegate) + } + + // MARK: - legacy + public init(frontText: String?, actionText: String?, backText: String?, actionBlock block: ActionBlock?) { + super.init(frame: CGRect.zero) + self.frontText = frontText + self.actionText = actionText + self.backText = backText + actionBlock = block + text = getTextFromStringComponents() + setup() + } + + public convenience init(actionMap: [AnyHashable: Any]?, + additionalData: [AnyHashable: Any]?, + actionDelegate delegate: ActionObjectDelegate?, + buttonDelegate: ButtonObjectDelegate?) { + + self.init(frontText: actionMap?.optionalStringForKey(KeyTitlePrefix), + actionText: actionMap?.optionalStringForKey(KeyTitle), + backText: actionMap?.optionalStringForKey(KeyTitlePostfix), + actionMap: actionMap, + additionalData: additionalData, + actionDelegate: delegate, + buttonDelegate: buttonDelegate) + } + + public convenience init(frontText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { + + self.init(frontText: frontText, actionText: actionMap?.optionalStringForKey(KeyTitle), backText: backText, actionMap: actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: buttonDelegate) + } + + public convenience init(frontText: String?, actionText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { + + self.init(frontText: frontText, actionText: actionText, backText: backText, actionMap: actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: nil) + } + + public convenience init(actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { + + self.init(frontText: actionMap?.optionalStringForKey(KeyTitlePrefix), actionText: actionMap?.optionalStringForKey(KeyTitle), backText: actionMap?.optionalStringForKey(KeyTitlePostfix), actionMap: actionMap, additionalData: additionalData, actionDelegate: delegate) + } + + public convenience init(frontText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { + + self.init(frontText: frontText, actionText: actionMap?.optionalStringForKey(KeyTitle), backText: backText, actionMap: actionMap, additionalData: additionalData, actionDelegate: delegate) + } + + // Convenience Initializer which assumes that the clickable text will be embedded in curly braces {}. + public convenience init(clickableTextEmbeddedInCurlyBraces fullText: String?, actionMapForClickableText actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { + + self.init(text: fullText, startTag: "{", endTag: "}", actionMap: actionMap, additionalData: additionalData, actionDelegate: delegate) + } + + public init(text fullText: String?, startTag: String?, endTag: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { + super.init(frame: CGRect.zero) + + setText(fullText, startTag: startTag, endTag: endTag) + + weak var weakDelegate: ActionObjectDelegate? = delegate + + actionBlock = { + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegate: weakDelegate as? CoreObjectActionLoadPresentDelegate) + } + } + + //------------------------------------------------------ + // MARK: - Configuration + //------------------------------------------------------ + + private func setup() { + + if self.label == nil { + let label = MFLabel(frame: CGRect.zero) + + backgroundColor = .clear + label.translatesAutoresizingMaskIntoConstraints = false + label.isUserInteractionEnabled = false + label.numberOfLines = 0 + label.lineBreakMode = NSLineBreakMode.byWordWrapping + label.setContentCompressionResistancePriority(.required, for: .vertical) + addSubview(label) + NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[label]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["label": label])) + NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0-[label]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["label": label])) + + self.label = label + label.sizeToFit() + } + + if normalTextColor == nil { + normalTextColor = .black + } + + if actionTextColor == nil { + actionTextColor = .black + } + + if normalTextFont == nil { + normalTextFont = MFStyler.fontB2() + } + + if actionTextFont == nil { + actionTextFont = MFStyler.fontB2() + } + + //adding the underline + setAlternateActionTextAttributes([NSAttributedString.Key.underlineStyle: NSNumber(value: NSUnderlineStyle.single.rawValue)]) + + self.label?.attributedText = attributedText + self.label?.accessibilityTraits = .button + } + + private func setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { + + weak var weakSelf: LabelWithInternalButton? = self + weak var weakDelegate: ActionObjectDelegate? = delegate + weak var weakButtonDelegate: ButtonObjectDelegate? = buttonDelegate + + actionBlock = { + var performAction = true + + if let wSelf = weakSelf, let wButtonDelegate = weakButtonDelegate, wButtonDelegate.responds(to: #selector(ButtonObjectDelegate.button(_:shouldPerformActionWithMap:additionalData:))) { + performAction = wButtonDelegate.button!(wSelf, shouldPerformActionWithMap: actionMap, additionalData: additionalData) + } + + if let wDelegate = weakDelegate as? CoreObjectActionLoadPresentDelegate, performAction { + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegate: wDelegate ) + } + } + } + + //------------------------------------------------------ + // MARK: - Methods + //------------------------------------------------------ + + @objc public func setFrontText(_ frontText: String?, actionMap: [AnyHashable: Any]?, backText: String?, additionalData: [AnyHashable: Any]?, delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { + + setFrontText(frontText, actionText: actionMap?.optionalStringForKey(KeyTitle), actionMap: actionMap, backText: backText, additionalData: additionalData, delegate: delegate, buttonDelegate: buttonDelegate) + } + + @objc public func setFrontText(_ frontText: String?, actionText: String?, actionMap: [AnyHashable: Any]?, backText: String?, additionalData: [AnyHashable: Any]?, delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { + + self.frontText = frontText + setActionMap(actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: buttonDelegate) + self.actionText = actionText + self.backText = backText + text = getTextFromStringComponents() + setup() + } + + @objc public func setFrontAttributedText(_ frontAttributedText: NSAttributedString?, actionMap: [AnyHashable: Any]?, backAttributedText backText: NSAttributedString?, additionalData: [AnyHashable: Any]?, delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { + + setFrontAttributedText(frontAttributedText, actionMap: actionMap, backAttributedText: backText, addNewLine: false, additionalData: additionalData, delegate: delegate, buttonDelegate: buttonDelegate) + } + + private func setFrontAttributedText(_ frontAttributedText: NSAttributedString?, actionMap: [AnyHashable: Any]?, backAttributedText: NSAttributedString?, addNewLine: Bool, additionalData: [AnyHashable: Any]?, delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { + + let mutableAttributedString = NSMutableAttributedString() + + if let frontAttributedText = frontAttributedText { + mutableAttributedString.append(frontAttributedText) + // Need to do this to fix the range issue + frontText = frontAttributedText.string + } + + let newLineAttributed = addNewLine ? "\n" : " " + + if let actions = actionMap, let actionMapCount = actionMap?.keys.count, actionMapCount > 0 { + + var actionString = actions.stringForkey(KeyTitle) + + if !actionString.isEmpty { + + actionString += newLineAttributed + + var actionAttributedString: NSAttributedString? + + if let b2Font = MFStyler.fontB2() { + actionAttributedString = MFStyler.styleGetAttributedString(actionString, font: b2Font, color: .black) + } + + actionText = actionString + setActionMap(actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: buttonDelegate) + + if let actionAttribString = actionAttributedString { + mutableAttributedString.append(actionAttribString) + } + } + } else { + actionText = nil + actionBlock = nil + } + + if let backAttributedText = backAttributedText { + mutableAttributedString.append(backAttributedText) + } + + attributedText = mutableAttributedString + + //added this line for underlining + setAlternateActionTextAttributes([NSAttributedString.Key.underlineStyle: NSNumber(value: NSUnderlineStyle.single.rawValue)]) + } + + @objc public func updateView(_ size: CGFloat) { + + //reset font for app size change + normalTextFont = MFStyler.fontB2() + actionTextFont = MFStyler.fontB2() + label?.attributedText = attributedText + } + + //------------------------------------------------------ + // MARK: - UIControl Override + //------------------------------------------------------ + + override open func touchesEnded(_ touches: Set, with event: UIEvent?) { + + if areTouches(inActionString: touches) { + sendActions(for: .touchUpInside) + if let action = actionBlock { + action() + } + } else { + sendActions(for: .touchUpOutside) + } + } + + private func areTouches(inActionString touches: Set?) -> Bool { + + if UIAccessibility.isVoiceOverRunning || makeWholeViewClickable { + return true + } + + let location: CGPoint? = touches?.first?.location(in: label) + let actionString = actionText + let index: Int = getActionRange().location + let rangeArray = getRangeArrayOfWords(in: actionString, withInitalIndex: index) + let rectArray = getRectArray(fromRangeArray: rangeArray) + var result = false + + for aValueOfRect in rectArray as? [NSValue] ?? [] { + let wordRect: CGRect = aValueOfRect.cgRectValue + + if let position = location, wordRect.contains(position) { + result = true + break + } else if wordRect.origin.x == 0 && wordRect.origin.y == 0 && wordRect.size.height == 0 && wordRect.size.width == 0 { + //incase word rect is not found for any reason, make the whole label to be clicable to avoid non functioning link in production. + result = true + break + } + } + + return result + } + + //------------------------------------------------------ + // MARK: - Helper + //------------------------------------------------------ + + private func getTextFromStringComponents() -> String? { + + if let frontTxt = frontText, !frontTxt.isEmpty { + frontText?.append(" ") + } + + if let actionTxt = actionText, !actionTxt.isEmpty { + actionText?.append(" ") + } + + return "\(frontText ?? "")\(actionText ?? "")\(backText ?? "")" + } + + private func getActionRange() -> NSRange { + + return NSRange(location: frontText?.count ?? 0, length: actionText?.count ?? 0) + } + + private func getFrontRange() -> NSRange { + + return NSRange(location: 0, length: frontText?.count ?? 0) + } + + private func getBackRange() -> NSRange { + + return NSRange(location: (frontText?.count ?? 0) + (actionText?.count ?? 0), length: backText?.count ?? 0) + } + + private func getRangeArrayOfWords(in string: String?, withInitalIndex index: Int) -> [Any]? { + + var index = index + let words = string?.components(separatedBy: " ") + var rangeArray = [AnyHashable]() + + for subString in words ?? [] { + let finalSubString = subString + (" ") + let wordIndex: Int = index + let length: Int = finalSubString.count + let subStringRange = NSRange(location: wordIndex, length: length) + let rangeValue = NSValue(range: subStringRange) + rangeArray.append(rangeValue) + index += length + } + + return rangeArray + } + + private func getRectArray(fromRangeArray rangeArray: [Any]?) -> [Any]? { + + var rectArray = [AnyHashable]() + + for aValueOfRange in rangeArray as? [NSValue] ?? [] { + let wordRange: NSRange = aValueOfRange.rangeValue + if let rect: CGRect = label?.boundingRect(forCharacterRange: wordRange) { + let rectValue = NSValue(cgRect: rect) + rectArray.append(rectValue) + } + } + + return rectArray + } + + @objc public func setCurlyBracedText(_ text: String) { + + setText(text, startTag: "{", endTag: "}") + } + + private func setText(_ text: String?, startTag: String?, endTag: String?) { + + let _text = text + let actionRange: NSRange = rangeOfText(_text, startTag: startTag, endTag: endTag) + + frontText = (_text as NSString?)?.substring(with: NSRange(location: 0, length: actionRange.location)) + actionText = (_text as NSString?)?.substring(with: actionRange) + + if let frontTextCount = frontText?.count, let actiontextCount = actionText?.count { + backText = (_text as NSString?)?.substring(with: NSRange(location: frontTextCount + actiontextCount, length: (_text?.count ?? 0) - frontTextCount - actiontextCount)) + } + + self.text = getTextFromStringComponents() + setup() + } + + // Not used + private func rangeOfCurlyBracedText(_ text: String?) -> NSRange { + + return rangeOfText(text, startTag: "{", endTag: "}") + } + + // TODO: Review this + private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> NSRange { + + var fullText = text + var range = NSRange(location: 0, length: 0) + let rangeOfLeftBrace: NSRange? = (fullText as NSString?)?.range(of: startTag ?? "") + + if rangeOfLeftBrace?.location != NSNotFound { + + if let rangeOfLeftBrace = rangeOfLeftBrace { + fullText = (fullText as NSString?)?.replacingCharacters(in: rangeOfLeftBrace, with: "") + } + let rangeOfRightBrace: NSRange? = (fullText as NSString?)?.range(of: endTag ?? "") + + if rangeOfRightBrace?.location != NSNotFound { + + let length: Int = (rangeOfRightBrace?.location ?? 0) - (rangeOfLeftBrace?.location ?? 0) + + if length > 0 { + range = NSRange(location: rangeOfLeftBrace?.location ?? 0, length: length) + if let rangeOfRightBrace = rangeOfRightBrace { + fullText = (fullText as NSString?)?.replacingCharacters(in: rangeOfRightBrace, with: "") + } + } + } + } + + return range + } + + @objc public func setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { + + setActionMap(actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: nil) + } + + // Reset the text and action map + @objc public func setTextWithClickableTextEmbeddedInCurlyBraces(_ text: String?, textAttributes attributes: [AnyHashable: Any]?, actionMapForClickableText actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { + + attributedText = NSAttributedString(string: text ?? "", attributes: attributes as? [NSAttributedString.Key: Any]) + setActionMap(actionMap, additionalData: additionalData, actionDelegate: delegate) + } + + @objc public func setWithText(_ fullText: String?, startTag: String?, endTag: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { + + setText(fullText, startTag: startTag, endTag: endTag) + setActionMap(actionMap, additionalData: additionalData, actionDelegate: delegate) + } + + @objc public func setFrontText(_ frontText: String?, actionMap: [AnyHashable: Any]?, backText: String?, additionalData: [AnyHashable: Any]?, delegate: ActionObjectDelegate?) { + + setFrontText(frontText, actionMap: actionMap, backText: backText, additionalData: additionalData, delegate: delegate, buttonDelegate: nil) + } + + // Reset the front text, back text, action map + @objc public func setFrontAttributedText(_ frontAttributedText: NSAttributedString?, actionMap: [AnyHashable: Any]?, backAttributedText: NSAttributedString?, additionalData: [AnyHashable: Any]?, delegate: ActionObjectDelegate?) { + + setFrontAttributedText(frontAttributedText, actionMap: actionMap, backAttributedText: backAttributedText, addNewLine: false, additionalData: additionalData, delegate: delegate) + } + + @objc public func setFrontAttributedText(_ frontAttributedText: NSAttributedString?, actionMap: [AnyHashable: Any]?, backAttributedText: NSAttributedString?, addNewLine: Bool, additionalData: [AnyHashable: Any]?, delegate: ActionObjectDelegate?) { + + setFrontAttributedText(frontAttributedText, actionMap: actionMap, backAttributedText: backAttributedText, addNewLine: addNewLine, additionalData: additionalData, delegate: delegate, buttonDelegate: nil) + } + + @objc public func setAlignment(_ textAlignment: NSTextAlignment) { + + label?.textAlignment = textAlignment + } + + @objc public func setAlternateActionTextAttributes(_ attributes: [AnyHashable: Any]?) { + + if let theseAttributes = attributes as? [NSAttributedString.Key: Any], let thisAttributedText = attributedText { + let attributedString = NSMutableAttributedString(attributedString: thisAttributedText) + attributedString.addAttributes(theseAttributes, range: getActionRange()) + attributedText = attributedString + } + } + + @objc public func setAlternateNormalTextAttributes(_ attributes: [AnyHashable: Any]?) { + + if let thisAttributedText = attributedText, let theseAttributes = attributes as? [NSAttributedString.Key: Any] { + let attributedString = NSMutableAttributedString(attributedString: thisAttributedText) + attributedString.addAttributes(theseAttributes, range: getFrontRange()) + attributedString.addAttributes(theseAttributes, range: getBackRange()) + attributedText = attributedString + } + } + + @objc public func setActionTextString(_ actionText: String?) { + + self.actionText = actionText + text = getTextFromStringComponents() + setup() + } + + /// Used to just reset the texts and actions if already initialized + @objc public func reset(withActionMap actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegate: ActionObjectDelegate?) { + + frontText = actionMap?.optionalStringForKey(KeyTitlePrefix) + actionText = actionMap?.optionalStringForKey(KeyTitle) + backText = actionMap?.optionalStringForKey(KeyTitlePostfix) + + weak var weakDelegate: ActionObjectDelegate? = delegate + + actionBlock = { + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegate: weakDelegate as? CoreObjectActionLoadPresentDelegate) + } + + text = getTextFromStringComponents() + setup() + } + + //------------------------------------------------------ + // MARK: - Accessibility + //------------------------------------------------------ + + // Not Used + @objc public func replaceSpace(withFakeSpace string: String?) -> String? { + + return string?.components(separatedBy: " ").joined(separator: "\u{00a0}") + } + + @objc override open func accessibilityActivate() -> Bool { + + if let action = actionBlock { + action() + return true + } + + return false + } + + @objc public func accessibilityCustomAction() -> UIAccessibilityCustomAction? { + + if let actionTxt = actionText, !actionTxt.isEmpty { + let name = actionTxt + return UIAccessibilityCustomAction(name: name, target: self, selector: #selector(LabelWithInternalButton.accessibilityCustomActions)) + } + + return UIAccessibilityCustomAction() + } + +} + + +extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol { + //------------------------------------------------------ + // MARK: - Atomization + //------------------------------------------------------ + + // Default values for view. + @objc open func setAsMolecule() { + + /* + + var frontText: String? + var actionText: String? + var backText: String? + var attributedText: NSAttributedString? + // By default, it will follow most of the font standard in zepplin, and should need to be changed + var normalTextFont: UIFont? + var actionTextFont: UIFont? + var normalTextColor: UIColor? + var actionTextColor: UIColor? + var alternateAttributeForActionText: String? + var makeWholeViewClickable = false + */ + } + + @objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) { + + // Configure class properties with JSON values + guard let jsonDictionary = json else { return } + + if let backgroundColorHex = jsonDictionary[KeyBackgroundColor] as? String { + backgroundColor = UIColor.mfGet(forHex: backgroundColorHex) + } + + // if let strokeColorHex = jsonDictionary["strokeColor"] as? String { + // strokeColor = UIColor.mfGet(forHex: strokeColorHex) + // } + // + // if let isHiddenValue = jsonDictionary[KeyIsHidden] as? Bool { + // isHidden = isHiddenValue + // } + // + // if let isOpaqueValue = jsonDictionary[KeyIsOpaque] as? Bool { + // isOpaque = isOpaqueValue + // } + // + // if let lineWidthValue = jsonDictionary["lineWidth"] as? CGFloat { + // lineWidth = lineWidthValue + // } + + + } + +} diff --git a/MVMCoreUI/MVMCoreUI.h b/MVMCoreUI/MVMCoreUI.h index 53ceeb3e..fea15913 100644 --- a/MVMCoreUI/MVMCoreUI.h +++ b/MVMCoreUI/MVMCoreUI.h @@ -74,7 +74,6 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[]; #pragma mark Views #import #import -#import #import #import #import From c791d7867185109239f010e10bfb2a3c01cba93a Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Fri, 29 Mar 2019 16:37:51 -0400 Subject: [PATCH 02/27] Working with ranges. Overall improvement of swift code. --- .../Atoms/Views/LabelWithInternalButton.swift | 254 +++++++++--------- 1 file changed, 122 insertions(+), 132 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index c87f0c54..10ad74dd 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -10,6 +10,7 @@ import MVMCore public typealias ActionBlock = () -> Void +private typealias ActionIndiciesTuple = (startIndex: String.Index?, endIndex: String.Index?, revisedText: String?) public typealias ActionObjectDelegate = (NSObject & MVMCoreActionDelegateProtocol) public typealias ButtonObjectDelegate = (NSObject & ButtonDelegateProtocol) public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProtocol & MVMCoreLoadDelegateProtocol & MVMCorePresentationDelegateProtocol & NSObjectProtocol @@ -23,15 +24,18 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt public var actionBlock: ActionBlock? public weak var label: MFLabel? - public var alternateAttributeForActionText: String? + // FIXME: I think there are scenarios where attributed text is being set with attributes but there is no text to set. public var attributedText: NSAttributedString? { didSet(newAttributedText) { - if newAttributedText != nil { - let mutableAttributedText = newAttributedText as? NSMutableAttributedString + if let newAttribText = newAttributedText, !newAttribText.string.isEmpty { + let mutableAttributedText = newAttribText as? NSMutableAttributedString let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = CGFloat(LabelWithInternalButtonLineSpace) - mutableAttributedText?.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttributedText?.length ?? 0)) + + if newAttribText.length > 0 { + mutableAttributedText?.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttribText.length)) + } if let mutableAttText = mutableAttributedText { label?.attributedText = mutableAttText @@ -41,10 +45,10 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt } // By default, it will follow most of the font standard in zepplin, and should need to be changed - public var normalTextFont: UIFont? - public var actionTextFont: UIFont? - public var normalTextColor: UIColor? - public var actionTextColor: UIColor? + public var normalTextFont: UIFont? = MFStyler.fontB2() + public var actionTextFont: UIFont? = MFStyler.fontB2() + public var normalTextColor: UIColor = .black + public var actionTextColor: UIColor = .black public var makeWholeViewClickable = false @@ -89,13 +93,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt setup() } - public init(frontText: String?, - actionText: String?, - backText: String?, - actionMap: [AnyHashable: Any]?, - additionalData: [AnyHashable: Any]?, - actionDelegate delegate: ActionObjectDelegate?, - buttonDelegate: ButtonObjectDelegate?) { + public init(frontText: String?, actionText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { super.init(frame: CGRect.zero) setFrontText(frontText, actionText: actionText, actionMap: actionMap, backText: backText, additionalData: additionalData, delegate: delegate, buttonDelegate: buttonDelegate) @@ -103,6 +101,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt // MARK: - legacy public init(frontText: String?, actionText: String?, backText: String?, actionBlock block: ActionBlock?) { + super.init(frame: CGRect.zero) self.frontText = frontText self.actionText = actionText @@ -112,18 +111,9 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt setup() } - public convenience init(actionMap: [AnyHashable: Any]?, - additionalData: [AnyHashable: Any]?, - actionDelegate delegate: ActionObjectDelegate?, - buttonDelegate: ButtonObjectDelegate?) { + public convenience init(actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { - self.init(frontText: actionMap?.optionalStringForKey(KeyTitlePrefix), - actionText: actionMap?.optionalStringForKey(KeyTitle), - backText: actionMap?.optionalStringForKey(KeyTitlePostfix), - actionMap: actionMap, - additionalData: additionalData, - actionDelegate: delegate, - buttonDelegate: buttonDelegate) + self.init(frontText: actionMap?.optionalStringForKey(KeyTitlePrefix), actionText: actionMap?.optionalStringForKey(KeyTitle), backText: actionMap?.optionalStringForKey(KeyTitlePostfix), actionMap: actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: buttonDelegate) } public convenience init(frontText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { @@ -187,22 +177,6 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt label.sizeToFit() } - if normalTextColor == nil { - normalTextColor = .black - } - - if actionTextColor == nil { - actionTextColor = .black - } - - if normalTextFont == nil { - normalTextFont = MFStyler.fontB2() - } - - if actionTextFont == nil { - actionTextFont = MFStyler.fontB2() - } - //adding the underline setAlternateActionTextAttributes([NSAttributedString.Key.underlineStyle: NSNumber(value: NSUnderlineStyle.single.rawValue)]) @@ -210,7 +184,8 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt self.label?.accessibilityTraits = .button } - private func setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { + private func + setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { weak var weakSelf: LabelWithInternalButton? = self weak var weakDelegate: ActionObjectDelegate? = delegate @@ -303,7 +278,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt @objc public func updateView(_ size: CGFloat) { - //reset font for app size change + // Reset font for app size change normalTextFont = MFStyler.fontB2() actionTextFont = MFStyler.fontB2() label?.attributedText = attributedText @@ -364,7 +339,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt frontText?.append(" ") } - if let actionTxt = actionText, !actionTxt.isEmpty { + if let actionTxt = actionText, !actionTxt.isEmpty, let backTxt = backText, !backTxt.isEmpty { actionText?.append(" ") } @@ -376,16 +351,6 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt return NSRange(location: frontText?.count ?? 0, length: actionText?.count ?? 0) } - private func getFrontRange() -> NSRange { - - return NSRange(location: 0, length: frontText?.count ?? 0) - } - - private func getBackRange() -> NSRange { - - return NSRange(location: (frontText?.count ?? 0) + (actionText?.count ?? 0), length: backText?.count ?? 0) - } - private func getRangeArrayOfWords(in string: String?, withInitalIndex index: Int) -> [Any]? { var index = index @@ -427,54 +392,42 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt private func setText(_ text: String?, startTag: String?, endTag: String?) { - let _text = text - let actionRange: NSRange = rangeOfText(_text, startTag: startTag, endTag: endTag) + guard let actionRange: ActionIndiciesTuple = rangeOfText(text, startTag: startTag, endTag: endTag) else { return } - frontText = (_text as NSString?)?.substring(with: NSRange(location: 0, length: actionRange.location)) - actionText = (_text as NSString?)?.substring(with: actionRange) - - if let frontTextCount = frontText?.count, let actiontextCount = actionText?.count { - backText = (_text as NSString?)?.substring(with: NSRange(location: frontTextCount + actiontextCount, length: (_text?.count ?? 0) - frontTextCount - actiontextCount)) + if let revisedText = actionRange.revisedText, let startBraceIndex = actionRange.startIndex, let endBraceIndex = actionRange.endIndex { + + frontText = String(revisedText[revisedText.startIndex.. NSRange { + + private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> ActionIndiciesTuple? { - return rangeOfText(text, startTag: "{", endTag: "}") - } - - // TODO: Review this - private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> NSRange { + var fullText = text ?? "" - var fullText = text - var range = NSRange(location: 0, length: 0) - let rangeOfLeftBrace: NSRange? = (fullText as NSString?)?.range(of: startTag ?? "") + guard let start = startTag, let end = endTag else { return nil } - if rangeOfLeftBrace?.location != NSNotFound { - - if let rangeOfLeftBrace = rangeOfLeftBrace { - fullText = (fullText as NSString?)?.replacingCharacters(in: rangeOfLeftBrace, with: "") - } - let rangeOfRightBrace: NSRange? = (fullText as NSString?)?.range(of: endTag ?? "") - - if rangeOfRightBrace?.location != NSNotFound { - - let length: Int = (rangeOfRightBrace?.location ?? 0) - (rangeOfLeftBrace?.location ?? 0) - - if length > 0 { - range = NSRange(location: rangeOfLeftBrace?.location ?? 0, length: length) - if let rangeOfRightBrace = rangeOfRightBrace { - fullText = (fullText as NSString?)?.replacingCharacters(in: rangeOfRightBrace, with: "") - } - } - } + if !fullText.contains(Character(start)) && !fullText.contains(Character(end)) { + return nil } - return range + var actionRange: ActionIndiciesTuple + + if let leftBrace = startTag, let rightBrace = endTag { + actionRange.startIndex = fullText.firstIndex(of: Character(leftBrace)) + fullText = fullText.replacingOccurrences(of: leftBrace, with: "") + + actionRange.endIndex = fullText.firstIndex(of: Character(rightBrace)) + fullText = fullText.replacingOccurrences(of: rightBrace, with: "") + } + + self.text = fullText + actionRange.revisedText = fullText + return actionRange } @objc public func setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { @@ -520,21 +473,38 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt if let theseAttributes = attributes as? [NSAttributedString.Key: Any], let thisAttributedText = attributedText { let attributedString = NSMutableAttributedString(attributedString: thisAttributedText) - attributedString.addAttributes(theseAttributes, range: getActionRange()) + if !attributedString.string.isEmpty { + attributedString.addAttributes(theseAttributes, range: getActionRange()) + } attributedText = attributedString } } @objc public func setAlternateNormalTextAttributes(_ attributes: [AnyHashable: Any]?) { - if let thisAttributedText = attributedText, let theseAttributes = attributes as? [NSAttributedString.Key: Any] { - let attributedString = NSMutableAttributedString(attributedString: thisAttributedText) - attributedString.addAttributes(theseAttributes, range: getFrontRange()) - attributedString.addAttributes(theseAttributes, range: getBackRange()) + if let _attributedText = attributedText, let _attributes = attributes as? [NSAttributedString.Key: Any] { + let attributedString = NSMutableAttributedString(attributedString: _attributedText) + if !attributedString.string.isEmpty { + attributedString.addAttributes(_attributes, range: getFrontRange()) + attributedString.addAttributes(_attributes, range: getBackRange()) + } attributedText = attributedString } } + private func getFrontRange() -> NSRange { + + return NSRange(location: 0, length: frontText?.count ?? 0) + } + + private func getBackRange() -> NSRange { + + let textLocation: Int = (frontText?.count ?? 0) + (actionText?.count ?? 0) + let rangeLength: Int = backText?.count ?? 0 + + return NSRange(location: textLocation, length: rangeLength) + } + @objc public func setActionTextString(_ actionText: String?) { self.actionText = actionText @@ -588,10 +558,8 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt return UIAccessibilityCustomAction() } - } - extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol { //------------------------------------------------------ // MARK: - Atomization @@ -600,48 +568,70 @@ extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol { // Default values for view. @objc open func setAsMolecule() { - /* - - var frontText: String? - var actionText: String? - var backText: String? - var attributedText: NSAttributedString? - // By default, it will follow most of the font standard in zepplin, and should need to be changed - var normalTextFont: UIFont? - var actionTextFont: UIFont? - var normalTextColor: UIColor? - var actionTextColor: UIColor? - var alternateAttributeForActionText: String? - var makeWholeViewClickable = false - */ } @objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) { // Configure class properties with JSON values - guard let jsonDictionary = json else { return } + guard let dictionary = json else { return } - if let backgroundColorHex = jsonDictionary[KeyBackgroundColor] as? String { - backgroundColor = UIColor.mfGet(forHex: backgroundColorHex) + if let backgroundColorHex = dictionary[KeyBackgroundColor] as? String { + self.backgroundColor = UIColor.mfGet(forHex: backgroundColorHex) } - // if let strokeColorHex = jsonDictionary["strokeColor"] as? String { - // strokeColor = UIColor.mfGet(forHex: strokeColorHex) - // } - // - // if let isHiddenValue = jsonDictionary[KeyIsHidden] as? Bool { - // isHidden = isHiddenValue - // } - // - // if let isOpaqueValue = jsonDictionary[KeyIsOpaque] as? Bool { - // isOpaque = isOpaqueValue - // } - // - // if let lineWidthValue = jsonDictionary["lineWidth"] as? CGFloat { - // lineWidth = lineWidthValue - // } + if let normalTextFont = dictionary["normalTextFont"] as? String, let normalSize = dictionary["normalSize"] as? CGFloat { + self.normalTextFont = UIFont(name: normalTextFont, size: normalSize) + } + if let actionTextFont = dictionary["actionTextFont"] as? String, let actionSize = dictionary["actionSize"] as? CGFloat { + self.actionTextFont = UIFont(name: actionTextFont, size: actionSize) + } + if let normalTextColorHex = dictionary["normalTextColor"] as? String { + self.normalTextColor = UIColor.mfGet(forHex: normalTextColorHex) + } + + if let actionTextColorHex = dictionary["actionTextColor"] as? String { + self.actionTextColor = UIColor.mfGet(forHex: actionTextColorHex) + } + + if let makeWholeViewClickable = dictionary["makeWholeViewClickable"] as? Bool { + self.makeWholeViewClickable = makeWholeViewClickable + } + + if let frontText = dictionary["frontText"] as? String { + self.frontText = frontText + } + + if let backText = dictionary["backText"] as? String { + self.backText = backText + } + + if let actionText = dictionary["actionText"] as? String { + self.actionText = actionText + } + + // Want this to be last because it has a didSet feature. + if let text = dictionary["text"] as? String { + self.text = text + } } - } + + +/* + public var actionBlock: ActionBlock? + + public var alternateAttributeForActionText: String? + + let mutableAttributedText = newAttributedText as? NSMutableAttributedString + let paragraphStyle = NSMutableParagraphStyle() + paragraphStyle.lineSpacing = CGFloat(LabelWithInternalButtonLineSpace) + mutableAttributedText?.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttributedText?.length ?? 0)) + + + override open var isEnabled: Bool { + didSet { + alpha = isEnabled ? 1 : DisableOppacity + } + */ From 27127aacfb315687736999f4ea8aa0627b4d0c5f Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Sun, 31 Mar 2019 21:08:11 -0400 Subject: [PATCH 03/27] WIP. Issues from language paradigms. Further work to resolve. --- .../Atoms/Views/LabelWithInternalButton.swift | 49 ++++++++++++------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index 10ad74dd..1ebe425e 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -45,10 +45,29 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt } // By default, it will follow most of the font standard in zepplin, and should need to be changed - public var normalTextFont: UIFont? = MFStyler.fontB2() - public var actionTextFont: UIFont? = MFStyler.fontB2() - public var normalTextColor: UIColor = .black - public var actionTextColor: UIColor = .black + public var normalTextFont: UIFont? = MFStyler.fontB2() { + didSet(newNormalFont) { + setAlternateNormalTextAttributes([NSAttributedString.Key.font: newNormalFont as Any]) + } + } + + public var actionTextFont: UIFont? = MFStyler.fontB2() { + didSet(newActionFont) { + setAlternateActionTextAttributes([NSAttributedString.Key.font: newActionFont as Any]) + } + } + + public var normalTextColor: UIColor = .black { + didSet(newNormalColor) { + setAlternateNormalTextAttributes([NSAttributedString.Key.foregroundColor: newNormalColor as Any]) + } + } + + public var actionTextColor: UIColor = .black { + didSet(newActionColor) { + setAlternateActionTextAttributes([NSAttributedString.Key.foregroundColor: newActionColor as Any]) + } + } public var makeWholeViewClickable = false @@ -333,7 +352,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt // MARK: - Helper //------------------------------------------------------ - private func getTextFromStringComponents() -> String? { + private func getTextFromStringComponents() -> String { if let frontTxt = frontText, !frontTxt.isEmpty { frontText?.append(" ") @@ -392,32 +411,27 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt private func setText(_ text: String?, startTag: String?, endTag: String?) { - guard let actionRange: ActionIndiciesTuple = rangeOfText(text, startTag: startTag, endTag: endTag) else { return } + let actionRange: ActionIndiciesTuple = rangeOfText(text, startTag: startTag, endTag: endTag) + + frontText = actionRange.revisedText if let revisedText = actionRange.revisedText, let startBraceIndex = actionRange.startIndex, let endBraceIndex = actionRange.endIndex { - + // TODO: Put some of this into a String Extension in MVMCore frontText = String(revisedText[revisedText.startIndex.. ActionIndiciesTuple? { + private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> ActionIndiciesTuple { var fullText = text ?? "" - - guard let start = startTag, let end = endTag else { return nil } - - if !fullText.contains(Character(start)) && !fullText.contains(Character(end)) { - return nil - } - var actionRange: ActionIndiciesTuple - if let leftBrace = startTag, let rightBrace = endTag { + if let leftBrace = startTag, let rightBrace = endTag, fullText.contains(Character(leftBrace)) && fullText.contains(Character(rightBrace)) { actionRange.startIndex = fullText.firstIndex(of: Character(leftBrace)) fullText = fullText.replacingOccurrences(of: leftBrace, with: "") @@ -427,6 +441,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt self.text = fullText actionRange.revisedText = fullText + return actionRange } From f68c355527ebd5b1d1421517d7cb9ff530ac6d3d Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Mon, 1 Apr 2019 10:08:11 -0400 Subject: [PATCH 04/27] name issue came from property observers. NewValue only appears in willSet, not didSet. --- .../Atoms/Views/LabelWithInternalButton.swift | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index 1ebe425e..46f64280 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -24,8 +24,6 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt public var actionBlock: ActionBlock? public weak var label: MFLabel? - // FIXME: I think there are scenarios where attributed text is being set with attributes but there is no text to set. - public var attributedText: NSAttributedString? { didSet(newAttributedText) { if let newAttribText = newAttributedText, !newAttribText.string.isEmpty { @@ -82,14 +80,14 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt public var backText: String? public var text: String? { - didSet(newText) { - if newText != nil { + willSet(newText) { +// if newText != nil { attributedText = NSAttributedString(string: newText ?? "") setAlternateNormalTextAttributes([NSAttributedString.Key.font: normalTextFont as Any]) setAlternateActionTextAttributes([NSAttributedString.Key.font: actionTextFont as Any]) setAlternateNormalTextAttributes([NSAttributedString.Key.foregroundColor: normalTextColor as Any]) setAlternateActionTextAttributes([NSAttributedString.Key.foregroundColor: actionTextColor as Any]) - } +// } } } @@ -196,7 +194,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt label.sizeToFit() } - //adding the underline + // Adding the underline setAlternateActionTextAttributes([NSAttributedString.Key.underlineStyle: NSNumber(value: NSUnderlineStyle.single.rawValue)]) self.label?.attributedText = attributedText @@ -423,6 +421,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt self.text = getTextFromStringComponents() } + self.text = actionRange.revisedText setup() } @@ -439,9 +438,8 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt fullText = fullText.replacingOccurrences(of: rightBrace, with: "") } - self.text = fullText - actionRange.revisedText = fullText + actionRange.revisedText = fullText return actionRange } From c5233a680d8c5e97f6fcfab4a5c7657a7c31c5e0 Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Mon, 1 Apr 2019 11:44:25 -0400 Subject: [PATCH 05/27] Further swapping of didSet/willSet. --- .../Atoms/Views/LabelWithInternalButton.swift | 90 +++++++------------ 1 file changed, 33 insertions(+), 57 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index 46f64280..ddbff108 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -25,7 +25,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt public weak var label: MFLabel? public var attributedText: NSAttributedString? { - didSet(newAttributedText) { + willSet(newAttributedText) { if let newAttribText = newAttributedText, !newAttribText.string.isEmpty { let mutableAttributedText = newAttribText as? NSMutableAttributedString let paragraphStyle = NSMutableParagraphStyle() @@ -44,25 +44,25 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt // By default, it will follow most of the font standard in zepplin, and should need to be changed public var normalTextFont: UIFont? = MFStyler.fontB2() { - didSet(newNormalFont) { + willSet(newNormalFont) { setAlternateNormalTextAttributes([NSAttributedString.Key.font: newNormalFont as Any]) } } public var actionTextFont: UIFont? = MFStyler.fontB2() { - didSet(newActionFont) { + willSet(newActionFont) { setAlternateActionTextAttributes([NSAttributedString.Key.font: newActionFont as Any]) } } public var normalTextColor: UIColor = .black { - didSet(newNormalColor) { + willSet(newNormalColor) { setAlternateNormalTextAttributes([NSAttributedString.Key.foregroundColor: newNormalColor as Any]) } } public var actionTextColor: UIColor = .black { - didSet(newActionColor) { + willSet(newActionColor) { setAlternateActionTextAttributes([NSAttributedString.Key.foregroundColor: newActionColor as Any]) } } @@ -81,13 +81,11 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt public var text: String? { willSet(newText) { -// if newText != nil { - attributedText = NSAttributedString(string: newText ?? "") - setAlternateNormalTextAttributes([NSAttributedString.Key.font: normalTextFont as Any]) - setAlternateActionTextAttributes([NSAttributedString.Key.font: actionTextFont as Any]) - setAlternateNormalTextAttributes([NSAttributedString.Key.foregroundColor: normalTextColor as Any]) - setAlternateActionTextAttributes([NSAttributedString.Key.foregroundColor: actionTextColor as Any]) -// } + attributedText = NSAttributedString(string: newText ?? "") + setAlternateNormalTextAttributes([NSAttributedString.Key.font: normalTextFont as Any]) + setAlternateActionTextAttributes([NSAttributedString.Key.font: actionTextFont as Any]) + setAlternateNormalTextAttributes([NSAttributedString.Key.foregroundColor: normalTextColor as Any]) + setAlternateActionTextAttributes([NSAttributedString.Key.foregroundColor: actionTextColor as Any]) } } @@ -111,15 +109,15 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt } public init(frontText: String?, actionText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { - super.init(frame: CGRect.zero) + setFrontText(frontText, actionText: actionText, actionMap: actionMap, backText: backText, additionalData: additionalData, delegate: delegate, buttonDelegate: buttonDelegate) } // MARK: - legacy public init(frontText: String?, actionText: String?, backText: String?, actionBlock block: ActionBlock?) { - super.init(frame: CGRect.zero) + self.frontText = frontText self.actionText = actionText self.backText = backText @@ -139,23 +137,19 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt } public convenience init(frontText: String?, actionText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { - self.init(frontText: frontText, actionText: actionText, backText: backText, actionMap: actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: nil) } public convenience init(actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { - self.init(frontText: actionMap?.optionalStringForKey(KeyTitlePrefix), actionText: actionMap?.optionalStringForKey(KeyTitle), backText: actionMap?.optionalStringForKey(KeyTitlePostfix), actionMap: actionMap, additionalData: additionalData, actionDelegate: delegate) } public convenience init(frontText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { - self.init(frontText: frontText, actionText: actionMap?.optionalStringForKey(KeyTitle), backText: backText, actionMap: actionMap, additionalData: additionalData, actionDelegate: delegate) } // Convenience Initializer which assumes that the clickable text will be embedded in curly braces {}. public convenience init(clickableTextEmbeddedInCurlyBraces fullText: String?, actionMapForClickableText actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { - self.init(text: fullText, startTag: "{", endTag: "}", actionMap: actionMap, additionalData: additionalData, actionDelegate: delegate) } @@ -226,7 +220,6 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt //------------------------------------------------------ @objc public func setFrontText(_ frontText: String?, actionMap: [AnyHashable: Any]?, backText: String?, additionalData: [AnyHashable: Any]?, delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { - setFrontText(frontText, actionText: actionMap?.optionalStringForKey(KeyTitle), actionMap: actionMap, backText: backText, additionalData: additionalData, delegate: delegate, buttonDelegate: buttonDelegate) } @@ -289,7 +282,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt attributedText = mutableAttributedString - //added this line for underlining + // Added this line for underlining setAlternateActionTextAttributes([NSAttributedString.Key.underlineStyle: NSNumber(value: NSUnderlineStyle.single.rawValue)]) } @@ -337,7 +330,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt result = true break } else if wordRect.origin.x == 0 && wordRect.origin.y == 0 && wordRect.size.height == 0 && wordRect.size.width == 0 { - //incase word rect is not found for any reason, make the whole label to be clicable to avoid non functioning link in production. + // Incase word rect is not found for any reason, make the whole label to be clicable to avoid non functioning link in production. result = true break } @@ -424,7 +417,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt self.text = actionRange.revisedText setup() } - + private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> ActionIndiciesTuple { var fullText = text ?? "" @@ -484,25 +477,25 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt @objc public func setAlternateActionTextAttributes(_ attributes: [AnyHashable: Any]?) { - if let theseAttributes = attributes as? [NSAttributedString.Key: Any], let thisAttributedText = attributedText { - let attributedString = NSMutableAttributedString(attributedString: thisAttributedText) - if !attributedString.string.isEmpty { - attributedString.addAttributes(theseAttributes, range: getActionRange()) - } - attributedText = attributedString + guard let theseAttributes = attributes as? [NSAttributedString.Key: Any], let thisAttributedText = attributedText else { return } + let attributedString = NSMutableAttributedString(attributedString: thisAttributedText) + + if !attributedString.string.isEmpty { + attributedString.addAttributes(theseAttributes, range: getActionRange()) } + attributedText = attributedString } - @objc public func setAlternateNormalTextAttributes(_ attributes: [AnyHashable: Any]?) { + public func setAlternateNormalTextAttributes(_ attributes: [AnyHashable: Any]?) { - if let _attributedText = attributedText, let _attributes = attributes as? [NSAttributedString.Key: Any] { - let attributedString = NSMutableAttributedString(attributedString: _attributedText) - if !attributedString.string.isEmpty { - attributedString.addAttributes(_attributes, range: getFrontRange()) - attributedString.addAttributes(_attributes, range: getBackRange()) - } - attributedText = attributedString + guard let _attributedText = attributedText, let _attributes = attributes as? [NSAttributedString.Key: Any] else { return } + let attributedString = NSMutableAttributedString(attributedString: _attributedText) + + if !attributedString.string.isEmpty { + attributedString.addAttributes(_attributes, range: getFrontRange()) + attributedString.addAttributes(_attributes, range: getBackRange()) } + attributedText = attributedString } private func getFrontRange() -> NSRange { @@ -565,8 +558,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt @objc public func accessibilityCustomAction() -> UIAccessibilityCustomAction? { if let actionTxt = actionText, !actionTxt.isEmpty { - let name = actionTxt - return UIAccessibilityCustomAction(name: name, target: self, selector: #selector(LabelWithInternalButton.accessibilityCustomActions)) + return UIAccessibilityCustomAction(name: actionTxt, target: self, selector: #selector(LabelWithInternalButton.accessibilityCustomActions)) } return UIAccessibilityCustomAction() @@ -624,27 +616,11 @@ extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol { self.actionText = actionText } - // Want this to be last because it has a didSet feature. + //public var actionBlock: ActionBlock? + + // Want this to be last because it has a willSet feature. if let text = dictionary["text"] as? String { self.text = text } } } - - -/* - public var actionBlock: ActionBlock? - - public var alternateAttributeForActionText: String? - - let mutableAttributedText = newAttributedText as? NSMutableAttributedString - let paragraphStyle = NSMutableParagraphStyle() - paragraphStyle.lineSpacing = CGFloat(LabelWithInternalButtonLineSpace) - mutableAttributedText?.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttributedText?.length ?? 0)) - - - override open var isEnabled: Bool { - didSet { - alpha = isEnabled ? 1 : DisableOppacity - } - */ From 16c644e12df047bec665877ad7142cde4cf326e8 Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Mon, 1 Apr 2019 13:28:15 -0400 Subject: [PATCH 06/27] Removed super call for setWithJSON. Provided more functionality for atom steup. --- MVMCoreUI/Atoms/Buttons/CaretButton.swift | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/CaretButton.swift b/MVMCoreUI/Atoms/Buttons/CaretButton.swift index af7d1d60..c85093d4 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretButton.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretButton.swift @@ -52,7 +52,7 @@ open class CaretButton: MFCustomButton { public func setEnabled(_ enabled: Bool) { super.isEnabled = enabled - + changeCaretColor() } @@ -112,21 +112,31 @@ open class CaretButton: MFCustomButton { } @objc override open func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) { - super.setWithJSON(json, delegate: delegate, additionalData: additionalData) - - // Configure class properties with JSON values + guard let jsonDictionary = json else { return } if let backgroundColorHex = jsonDictionary[KeyBackgroundColor] as? String { backgroundColor = UIColor.mfGet(forHex: backgroundColorHex) } - if let enableColorHex = jsonDictionary["enableColor"] as? String { + if let enableColorHex = jsonDictionary["enabledColor"] as? String { enabledColor = UIColor.mfGet(forHex: enableColorHex) } if let disabledColorHex = jsonDictionary["disabledColor"] as? String { disabledColor = UIColor.mfGet(forHex: disabledColorHex) } + + if let caretViewHeight = jsonDictionary["caretViewHeight"] as? NSNumber { + rightViewHeight = caretViewHeight + } + + if let caretViewWidth = jsonDictionary["caretViewWidth"] as? NSNumber { + rightViewWidth = caretViewWidth + } + + if let buttonText = jsonDictionary["buttonText"] as? String { + setTitle(buttonText, for: .normal) + } } } From bd69d9fb891b2e209bd7fd48ab82d8343b58a94d Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Mon, 1 Apr 2019 14:10:47 -0400 Subject: [PATCH 07/27] mild changes. --- MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index ddbff108..1d8ec52a 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -368,7 +368,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt var rangeArray = [AnyHashable]() for subString in words ?? [] { - let finalSubString = subString + (" ") + let finalSubString = subString + " " let wordIndex: Int = index let length: Int = finalSubString.count let subStringRange = NSRange(location: wordIndex, length: length) @@ -407,7 +407,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt frontText = actionRange.revisedText if let revisedText = actionRange.revisedText, let startBraceIndex = actionRange.startIndex, let endBraceIndex = actionRange.endIndex { - // TODO: Put some of this into a String Extension in MVMCore + frontText = String(revisedText[revisedText.startIndex.. Date: Thu, 4 Apr 2019 09:29:54 -0400 Subject: [PATCH 08/27] added @class. --- MVMCoreUI/Styles/MFStyler.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Styles/MFStyler.h b/MVMCoreUI/Styles/MFStyler.h index 2020d5c6..3a30ad6c 100644 --- a/MVMCoreUI/Styles/MFStyler.h +++ b/MVMCoreUI/Styles/MFStyler.h @@ -9,7 +9,7 @@ #import #import - +@class LabelWithInternalButton; @class MFSizeObject; //enum for border From 14d66d1fc60c93e9731a44bf5b0645f5efac44cc Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Thu, 4 Apr 2019 13:18:06 -0400 Subject: [PATCH 09/27] only used internally --- MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index 1d8ec52a..cda4d6ec 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -27,6 +27,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt public var attributedText: NSAttributedString? { willSet(newAttributedText) { if let newAttribText = newAttributedText, !newAttribText.string.isEmpty { + let mutableAttributedText = newAttribText as? NSMutableAttributedString let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = CGFloat(LabelWithInternalButtonLineSpace) @@ -79,7 +80,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt public var actionText: String? public var backText: String? - public var text: String? { + private var text: String? { willSet(newText) { attributedText = NSAttributedString(string: newText ?? "") setAlternateNormalTextAttributes([NSAttributedString.Key.font: normalTextFont as Any]) From baa0f3d3f7bd5f0faa485924ddaa79fc0c1a41b6 Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Thu, 4 Apr 2019 13:39:59 -0400 Subject: [PATCH 10/27] Fixed how NSMutableAttribute is used. --- MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index cda4d6ec..2473bf85 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -28,17 +28,14 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt willSet(newAttributedText) { if let newAttribText = newAttributedText, !newAttribText.string.isEmpty { - let mutableAttributedText = newAttribText as? NSMutableAttributedString + let mutableAttributedText = NSMutableAttributedString(attributedString: newAttribText) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = CGFloat(LabelWithInternalButtonLineSpace) if newAttribText.length > 0 { - mutableAttributedText?.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttribText.length)) - } - - if let mutableAttText = mutableAttributedText { - label?.attributedText = mutableAttText + mutableAttributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttribText.length)) } + label?.attributedText = mutableAttributedText } } } From 3ee784ccb03070fcfc77f28c47a7e5fe5ec3aad8 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 9 Apr 2019 10:38:26 -0400 Subject: [PATCH 11/27] Changes for new feed template --- MVMCoreUI/Atoms/Buttons/PrimaryButton.h | 4 ++-- MVMCoreUI/Atoms/Buttons/PrimaryButton.m | 4 ++++ MVMCoreUI/Molecules/TwoButtonView.swift | 14 +++++++++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/PrimaryButton.h b/MVMCoreUI/Atoms/Buttons/PrimaryButton.h index fb93c33a..771f8c01 100644 --- a/MVMCoreUI/Atoms/Buttons/PrimaryButton.h +++ b/MVMCoreUI/Atoms/Buttons/PrimaryButton.h @@ -62,8 +62,8 @@ static CGFloat const PrimaryButtonSmallHeight = 30.0; + (nullable instancetype)primaryGraySmallRedButton; + (nullable instancetype)primaryWhiteSmallRedButton; - - +// Returns the current height of the button. +- (CGFloat)getHeight; #pragma mark - For Subclassing diff --git a/MVMCoreUI/Atoms/Buttons/PrimaryButton.m b/MVMCoreUI/Atoms/Buttons/PrimaryButton.m index 5a708f2c..fd7ad2b9 100644 --- a/MVMCoreUI/Atoms/Buttons/PrimaryButton.m +++ b/MVMCoreUI/Atoms/Buttons/PrimaryButton.m @@ -86,6 +86,10 @@ #pragma mark - Sizing +- (CGFloat)getHeight { + return self.height.constant; +} + - (MFSizeObject *)innerPadding { return [MFSizeObject sizeObjectWithStandardSize:24.0 standardiPadPortraitSize:32.0 iPadProLandscapeSize:36.0]; } diff --git a/MVMCoreUI/Molecules/TwoButtonView.swift b/MVMCoreUI/Molecules/TwoButtonView.swift index 9e6cf4ee..ee03ff49 100644 --- a/MVMCoreUI/Molecules/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/TwoButtonView.swift @@ -41,11 +41,7 @@ import UIKit } let primaryButtonMap = json?.optionalDictionaryForKey("primaryButton") let secondaryButtonMap = json?.optionalDictionaryForKey("secondaryButton") - setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, legacy: false) - primaryButton?.setAsStandardCustom() - secondaryButton?.setAsSecondaryCustom() - primaryButton?.setWithJSON(primaryButtonMap, delegate: delegate, additionalData: additionalData) - secondaryButton?.setWithJSON(secondaryButtonMap, delegate: delegate, additionalData: additionalData) + set(primaryButtonJSON: primaryButtonMap, secondaryButtonJSON: secondaryButtonMap, actionDelegate: delegate, additionalData: additionalData, buttonDelegate: delegate) } // MARK: - Constraining @@ -141,6 +137,14 @@ import UIKit } } + open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { + setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON, legacy: false) + primaryButton?.setAsStandardCustom() + secondaryButton?.setAsSecondaryCustom() + primaryButton?.setWithJSON(primaryButtonJSON, delegate: actionDelegate as? NSObject, additionalData: additionalData) + secondaryButton?.setWithJSON(secondaryButtonJSON, delegate: actionDelegate as? NSObject, additionalData: additionalData) + } + // MARK: - Legacy open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton) From 741785cc228129c1acfb2424ce7d3fdf6e750c9d Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 9 Apr 2019 13:46:28 -0400 Subject: [PATCH 12/27] secondary default as white for the feed --- MVMCoreUI/Molecules/TwoButtonView.swift | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Molecules/TwoButtonView.swift b/MVMCoreUI/Molecules/TwoButtonView.swift index ee03ff49..66ef8600 100644 --- a/MVMCoreUI/Molecules/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/TwoButtonView.swift @@ -25,6 +25,11 @@ import UIKit super.init(frame: frame) } + public func setDefaultCustom() { + primaryButton?.setAsStandardCustom() + secondaryButton?.setAsSecondaryCustom() + } + // MARK: - MVMCoreViewProtocol open override func updateView(_ size: CGFloat) { super.updateView(size) @@ -139,8 +144,7 @@ import UIKit open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON, legacy: false) - primaryButton?.setAsStandardCustom() - secondaryButton?.setAsSecondaryCustom() + setDefaultCustom() primaryButton?.setWithJSON(primaryButtonJSON, delegate: actionDelegate as? NSObject, additionalData: additionalData) secondaryButton?.setWithJSON(secondaryButtonJSON, delegate: actionDelegate as? NSObject, additionalData: additionalData) } From 6114bbbf92fd8910cf09a1005f09677c7a569066 Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Tue, 9 Apr 2019 14:43:06 -0400 Subject: [PATCH 13/27] changed the protocol type. --- MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index 85f628fe..ea3323d1 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -11,8 +11,8 @@ import MVMCore public typealias ActionBlock = () -> Void private typealias ActionIndiciesTuple = (startIndex: String.Index?, endIndex: String.Index?, revisedText: String?) -public typealias ActionObjectDelegate = (NSObject & MVMCoreActionDelegateProtocol) -public typealias ButtonObjectDelegate = (NSObject & ButtonDelegateProtocol) +public typealias ActionObjectDelegate = (NSObjectProtocol & MVMCoreActionDelegateProtocol) +public typealias ButtonObjectDelegate = (NSObjectProtocol & ButtonDelegateProtocol) public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProtocol & MVMCoreLoadDelegateProtocol & MVMCorePresentationDelegateProtocol & NSObjectProtocol From 503bbc46054fcb66b7b5edbcc7d3f5623226e567 Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Wed, 10 Apr 2019 10:06:53 -0400 Subject: [PATCH 14/27] removed redundant check. --- MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index ea3323d1..7b5ba239 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -31,10 +31,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt let mutableAttributedText = NSMutableAttributedString(attributedString: newAttribText) let paragraphStyle = NSMutableParagraphStyle() paragraphStyle.lineSpacing = CGFloat(LabelWithInternalButtonLineSpace) - - if newAttribText.length > 0 { - mutableAttributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttribText.length)) - } + mutableAttributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttribText.length)) label?.attributedText = mutableAttributedText } } From d0bc96e3a5e9f516190d9469c1e25ae6be9f8d38 Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Wed, 10 Apr 2019 12:12:44 -0400 Subject: [PATCH 15/27] Corrections made. --- .../Atoms/Views/LabelWithInternalButton.swift | 50 +++++++------------ 1 file changed, 17 insertions(+), 33 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index 7b5ba239..3810294a 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -105,7 +105,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt public init(frontText: String?, actionText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) { super.init(frame: CGRect.zero) - + setFrontText(frontText, actionText: actionText, actionMap: actionMap, backText: backText, additionalData: additionalData, delegate: delegate, buttonDelegate: buttonDelegate) } @@ -170,10 +170,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt let label = MFLabel(frame: CGRect.zero) backgroundColor = .clear - label.translatesAutoresizingMaskIntoConstraints = false label.isUserInteractionEnabled = false - label.numberOfLines = 0 - label.lineBreakMode = NSLineBreakMode.byWordWrapping label.setContentCompressionResistancePriority(.required, for: .vertical) addSubview(label) NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0-[label]-0-|", options: .directionLeadingToTrailing, metrics: nil, views: ["label": label])) @@ -201,11 +198,11 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt var performAction = true if let wSelf = weakSelf, let wButtonDelegate = weakButtonDelegate, wButtonDelegate.responds(to: #selector(ButtonObjectDelegate.button(_:shouldPerformActionWithMap:additionalData:))) { - performAction = wButtonDelegate.button!(wSelf, shouldPerformActionWithMap: actionMap, additionalData: additionalData) + performAction = wButtonDelegate.button?(wSelf, shouldPerformActionWithMap: actionMap, additionalData: additionalData) ?? false } if let wDelegate = weakDelegate as? CoreObjectActionLoadPresentDelegate, performAction { - MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegate: wDelegate ) + MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegate: wDelegate) } } } @@ -243,29 +240,17 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt frontText = frontAttributedText.string } - let newLineAttributed = addNewLine ? "\n" : " " - - if let actions = actionMap, let actionMapCount = actionMap?.keys.count, actionMapCount > 0 { + if let b2Font = MFStyler.fontB2(), + let actions = actionMap, + actions.keys.count > 0, + let actionString = actions.optionalStringForKey(KeyTitle), + !actionString.isEmpty { - var actionString = actions.stringForkey(KeyTitle) + let actionStringOnLine = actionString + (addNewLine ? "\n" : " ") + actionText = actionStringOnLine + setActionMap(actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: buttonDelegate) + mutableAttributedString.append(MFStyler.styleGetAttributedString(actionStringOnLine, font: b2Font, color: .black)) - if !actionString.isEmpty { - - actionString += newLineAttributed - - var actionAttributedString: NSAttributedString? - - if let b2Font = MFStyler.fontB2() { - actionAttributedString = MFStyler.styleGetAttributedString(actionString, font: b2Font, color: .black) - } - - actionText = actionString - setActionMap(actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: buttonDelegate) - - if let actionAttribString = actionAttributedString { - mutableAttributedString.append(actionAttribString) - } - } } else { actionText = nil actionBlock = nil @@ -276,7 +261,6 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt } attributedText = mutableAttributedString - // Added this line for underlining setAlternateActionTextAttributes([NSAttributedString.Key.underlineStyle: NSNumber(value: NSUnderlineStyle.single.rawValue)]) } @@ -399,17 +383,17 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt let actionRange: ActionIndiciesTuple = rangeOfText(text, startTag: startTag, endTag: endTag) - frontText = actionRange.revisedText - if let revisedText = actionRange.revisedText, let startBraceIndex = actionRange.startIndex, let endBraceIndex = actionRange.endIndex { - + frontText = String(revisedText[revisedText.startIndex.. Date: Wed, 10 Apr 2019 12:43:39 -0400 Subject: [PATCH 16/27] button_delegate --- MVMCoreUI/Molecules/TwoButtonView.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/MVMCoreUI/Molecules/TwoButtonView.swift b/MVMCoreUI/Molecules/TwoButtonView.swift index 9e6cf4ee..03f9f67b 100644 --- a/MVMCoreUI/Molecules/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/TwoButtonView.swift @@ -172,7 +172,7 @@ import UIKit public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: AnyHashable]?, buttonDelegate: Any?) { self.init() - setup(withButtonMap: buttonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonMap) + setup(withButtonMap: buttonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) primaryButton?.setAsSmall(small) secondaryButton?.setAsSmall(small) } From 074efcbf1d4417642946761ae437e001e8950ab0 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Wed, 10 Apr 2019 15:49:07 -0400 Subject: [PATCH 17/27] layout margins --- MVMCoreUI/Atoms/Views/ViewConstrainingView.m | 1 - .../MVMCoreUIStackableViewController.h | 6 ++- .../MVMCoreUIStackableViewController.m | 37 ++++++++++++++----- .../ThreeLayerViewController.swift | 24 ++++++------ .../NSLayoutConstraint+MFConvenience.h | 7 ++++ .../NSLayoutConstraint+MFConvenience.m | 18 +++++++++ MVMCoreUI/Molecules/MoleculeStackView.swift | 7 ++-- MVMCoreUI/Styles/MFStyler.h | 1 + MVMCoreUI/Styles/MFStyler.m | 12 ++++++ 9 files changed, 86 insertions(+), 27 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/ViewConstrainingView.m b/MVMCoreUI/Atoms/Views/ViewConstrainingView.m index a88b61c3..780b65aa 100644 --- a/MVMCoreUI/Atoms/Views/ViewConstrainingView.m +++ b/MVMCoreUI/Atoms/Views/ViewConstrainingView.m @@ -138,7 +138,6 @@ #pragma mark - MVMCoreUIMoleculeViewProtocol - (void)setAsMolecule { - self.updateViewHorizontalDefaults = YES; } @end diff --git a/MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.h b/MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.h index 9e7d352e..0c702925 100644 --- a/MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.h +++ b/MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.h @@ -29,13 +29,15 @@ // Returns the standard space around ui objects. + (UIEdgeInsets)standardSpaceAroundUIObjectForSize:(CGFloat)size; -// Consolidates generateFormViewWithUIArray and spaceArroundUIObject into one class object so other view controllers can take advantage of these functions. +// Consolidates generateFormViewWithUIArray and spaceArroundUIObject into one class object so other view controllers can take advantage of these functions. By default does not pin to margins. + (void)populateView:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock; ++ (void)populateView:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray useMargins:(BOOL)useMargins withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock; + (void)populateViewHorizontally:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock; + (void)populateView:(nonnull UIView *)view withUIArrayForConstrainingViews:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock; -// Does the actual laying out. The formuiarray views should already be added to the view. +// Does the actual laying out. The formuiarray views should already be added to the view. By default does not pin to margins + (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock; ++ (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray useMargins:(BOOL)useMargins withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock; + (void)autoLayoutViewHorizontally:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock; + (void)autoLayoutViewWithConstrainingViewsWithUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock; diff --git a/MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.m b/MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.m index 86f4ebfe..7a14762a 100644 --- a/MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.m +++ b/MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.m @@ -10,6 +10,7 @@ #import "MFStyler.h" #import "ViewConstrainingView.h" #import "MVMCoreUIUtility.h" +#import "NSLayoutConstraint+MFConvenience.h" @interface MVMCoreUIStackableViewController () @end @@ -69,11 +70,15 @@ } + (void)populateView:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock { + [self populateView:view withUIArray:formUIArray useMargins:NO withSpacingBlock:spacingBlock]; +} + ++ (void)populateView:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray useMargins:(BOOL)useMargins withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock { if ([formUIArray count] > 0) { for (UIView *subview in formUIArray) { [view addSubview:subview]; } - [MVMCoreUIStackableViewController autoLayoutView:view withUIArray:formUIArray withSpacingBlock:spacingBlock]; + [MVMCoreUIStackableViewController autoLayoutView:view withUIArray:formUIArray useMargins:useMargins withSpacingBlock:spacingBlock]; } } @@ -96,34 +101,46 @@ } } -+ (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock { ++ (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray useMargins:(BOOL)useMargins withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock { if ([formUIArray count] > 0) { // Adds the first object to the view and pins it to the top of the content view. - id previousUIObject = [formUIArray objectAtIndex:0]; - UIEdgeInsets spaceAroundObjectPrevious = spacingBlock(previousUIObject); + UIView *previousUIObject = [formUIArray objectAtIndex:0]; [previousUIObject setTranslatesAutoresizingMaskIntoConstraints:NO]; - [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-top@999-[previousUIObject]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"top":@(spaceAroundObjectPrevious.top)} views:NSDictionaryOfVariableBindings(previousUIObject)]]; - [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-left@999-[previousUIObject]-right-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"left":@(spaceAroundObjectPrevious.left),@"right":@(spaceAroundObjectPrevious.right)} views:NSDictionaryOfVariableBindings(previousUIObject)]]; + UIEdgeInsets spaceAroundObjectPrevious = spacingBlock(previousUIObject); + NSLayoutConstraint *constraint = [NSLayoutConstraint pinViewTopToSuperview:previousUIObject useMargins:useMargins constant:spaceAroundObjectPrevious.top]; + constraint.priority = 999; + constraint.active = YES; + constraint = [NSLayoutConstraint pinViewLeftToSuperview:previousUIObject useMargins:useMargins constant:spaceAroundObjectPrevious.left]; + constraint.priority = 999; + constraint.active = YES; + [NSLayoutConstraint pinViewRightToSuperview:previousUIObject useMargins:useMargins constant:spaceAroundObjectPrevious.right].active = YES; // Sets the horizontal spacing and adds vertical spacing between all ui objects. for (NSUInteger i = 1; i < [formUIArray count]; i++) { - id uiObject = [formUIArray objectAtIndex:i]; + UIView *uiObject = [formUIArray objectAtIndex:i]; UIEdgeInsets spaceAroundObjectCurrent = spacingBlock(uiObject); [uiObject setTranslatesAutoresizingMaskIntoConstraints:NO]; [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previousUIObject]-space-[uiObject]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"space":@(spaceAroundObjectPrevious.bottom + spaceAroundObjectCurrent.top)} views:NSDictionaryOfVariableBindings(previousUIObject,uiObject)]]; - [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-left@999-[uiObject]-right-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"left":@(spaceAroundObjectCurrent.left),@"right":@(spaceAroundObjectCurrent.right)} views:NSDictionaryOfVariableBindings(uiObject)]]; - + constraint = [NSLayoutConstraint pinViewLeftToSuperview:uiObject useMargins:useMargins constant:spaceAroundObjectCurrent.left]; + constraint.priority = 999; + constraint.active = YES; + [NSLayoutConstraint pinViewRightToSuperview:uiObject useMargins:useMargins constant:spaceAroundObjectCurrent.right].active = YES; + previousUIObject = uiObject; spaceAroundObjectPrevious = spaceAroundObjectCurrent; } // Pins the last object to the bottom of the content view. - [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[previousUIObject]-bottom-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"bottom":@(spaceAroundObjectPrevious.bottom)} views:NSDictionaryOfVariableBindings(previousUIObject)]]; + [NSLayoutConstraint pinViewBottomToSuperview:previousUIObject useMargins:useMargins constant:spaceAroundObjectPrevious.bottom].active = YES; } } ++ (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock { + [self autoLayoutView:view withUIArray:formUIArray useMargins:NO withSpacingBlock:spacingBlock]; +} + + (void)autoLayoutViewHorizontally:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock { if ([formUIArray count] > 0) { diff --git a/MVMCoreUI/BaseControllers/ThreeLayerViewController.swift b/MVMCoreUI/BaseControllers/ThreeLayerViewController.swift index c1fadf55..2573388c 100644 --- a/MVMCoreUI/BaseControllers/ThreeLayerViewController.swift +++ b/MVMCoreUI/BaseControllers/ThreeLayerViewController.swift @@ -16,6 +16,7 @@ open class ThreeLayerViewController: ProgrammaticScrollViewController { var topView: UIView? var middleView: UIView? var bottomView: UIView? + var useMargins: Bool = true // The bottom view can be put outside of the scrolling area. var bottomViewOutsideOfScroll = false @@ -26,6 +27,7 @@ open class ThreeLayerViewController: ProgrammaticScrollViewController { open override func updateViews() { super.updateViews() let width = view.bounds.width + MFStyler.setDefaultMarginsFor(contentView, size: width) if let topView = topView as? MVMCoreViewProtocol { topView.updateView(width) } @@ -116,9 +118,9 @@ extension ThreeLayerViewController { return nil } contentView.addSubview(topView) - topView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true - contentView.rightAnchor.constraint(equalTo: topView.rightAnchor).isActive = true - topView.topAnchor.constraint(equalTo: contentView.topAnchor).isActive = true + NSLayoutConstraint.pinViewTop(toSuperview: topView, useMargins: useMargins, constant: 0).isActive = true + NSLayoutConstraint.pinViewLeft(toSuperview: topView, useMargins: useMargins, constant: 0).isActive = true + NSLayoutConstraint.pinViewRight(toSuperview: topView, useMargins: useMargins, constant: 0).isActive = true return topView } @@ -133,8 +135,8 @@ extension ThreeLayerViewController { return nil } contentView.addSubview(middleView) - middleView.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true - contentView.rightAnchor.constraint(equalTo: middleView.rightAnchor).isActive = true + NSLayoutConstraint.pinViewLeft(toSuperview: middleView, useMargins: useMargins, constant: 0).isActive = true + NSLayoutConstraint.pinViewRight(toSuperview: middleView, useMargins: useMargins, constant: 0).isActive = true middleView.setContentHuggingPriority(UILayoutPriority.required, for: NSLayoutConstraint.Axis.vertical) return middleView } @@ -220,17 +222,17 @@ extension ThreeLayerViewController { return } contentView.addSubview(view); - contentView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true - contentView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true - view.leftAnchor.constraint(equalTo: contentView.leftAnchor).isActive = true + NSLayoutConstraint.pinViewLeft(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true + NSLayoutConstraint.pinViewRight(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true + NSLayoutConstraint.pinViewBottom(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true } func addViewOutsideOfScrollViewBottom(_ view: UIView) { self.view?.addSubview(view) if let scrollView = scrollView, let parentView = self.view { view.topAnchor.constraint(equalTo: scrollView.bottomAnchor).isActive = true - view.leftAnchor.constraint(equalTo: parentView.leftAnchor).isActive = true - parentView.rightAnchor.constraint(equalTo: view.rightAnchor).isActive = true + NSLayoutConstraint.pinViewLeft(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true + NSLayoutConstraint.pinViewRight(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true if #available(iOS 11.0, *) { parentView.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true if let safeAreaView = MVMCoreUICommonViewsUtility.getAndSetupSafeAreaView(on: parentView) { @@ -238,7 +240,7 @@ extension ThreeLayerViewController { self.safeAreaView = safeAreaView } } else { - parentView.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true + NSLayoutConstraint.pinViewBottom(toSuperview: view, useMargins: useMargins, constant: 0).isActive = true } } } diff --git a/MVMCoreUI/Categories/NSLayoutConstraint+MFConvenience.h b/MVMCoreUI/Categories/NSLayoutConstraint+MFConvenience.h index ed9d1876..c8e12cae 100644 --- a/MVMCoreUI/Categories/NSLayoutConstraint+MFConvenience.h +++ b/MVMCoreUI/Categories/NSLayoutConstraint+MFConvenience.h @@ -55,6 +55,13 @@ extern NSString * _Nonnull const ConstraintWidth; +(nullable NSDictionary *)constraintAlignView :(nonnull UIView *)firstView toSecondView :(nonnull UIView *)secondView alignX :(BOOL)alignX alignY :(BOOL)alignY; +#pragma mark - With Margins + ++ (nonnull NSLayoutConstraint *)pinViewTopToSuperview:(nonnull UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant; ++ (nonnull NSLayoutConstraint *)pinViewLeftToSuperview:(nonnull UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant; ++ (nonnull NSLayoutConstraint *)pinViewRightToSuperview:(nonnull UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant; ++ (nonnull NSLayoutConstraint *)pinViewBottomToSuperview:(nonnull UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant; + #pragma mark - Scaling constraints // These functions will pin a view to its super view with space that is a ratio of the anchor (by default the super view's width if nothing is passed in). (So if the space is 24 and the super's width is 320 in the design, then the ratio should be 24/320 and this will be multiplied by the super's current width, so that the constraint always linearly scales). diff --git a/MVMCoreUI/Categories/NSLayoutConstraint+MFConvenience.m b/MVMCoreUI/Categories/NSLayoutConstraint+MFConvenience.m index 1ed0acd1..39a315c1 100644 --- a/MVMCoreUI/Categories/NSLayoutConstraint+MFConvenience.m +++ b/MVMCoreUI/Categories/NSLayoutConstraint+MFConvenience.m @@ -150,6 +150,24 @@ NSString *const ConstraintWidth = @"width"; return constraintsDictionary; } +#pragma mark - With Margins + ++ (NSLayoutConstraint *)pinViewTopToSuperview:(UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant { + return [view.topAnchor constraintEqualToAnchor:(useMargins ? view.superview.layoutMarginsGuide.topAnchor : view.superview.topAnchor) constant:constant]; +} + ++ (NSLayoutConstraint *)pinViewLeftToSuperview:(UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant { + return [view.leftAnchor constraintEqualToAnchor:(useMargins ? view.superview.layoutMarginsGuide.leftAnchor : view.superview.leftAnchor) constant:constant]; +} + ++ (NSLayoutConstraint *)pinViewRightToSuperview:(UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant { + return [(useMargins ? view.superview.layoutMarginsGuide.rightAnchor : view.superview.rightAnchor) constraintEqualToAnchor:view.rightAnchor constant:constant]; +} + ++ (NSLayoutConstraint *)pinViewBottomToSuperview:(UIView *)view useMargins:(BOOL)useMargins constant:(CGFloat)constant { + return [(useMargins ? view.superview.layoutMarginsGuide.bottomAnchor : view.superview.bottomAnchor) constraintEqualToAnchor:view.bottomAnchor constant:constant]; +} + #pragma mark - Scaling constraints + (nullable NSDictionary *)scalingConstraintPinSubview:(nullable UIView *)subview pinTop:(BOOL)pinTop topConstant:(CGFloat)topConstant pinBottom:(BOOL)pinBottom bottomConstant:(CGFloat)bottomConstant pinLeft:(BOOL)pinLeft leftConstant:(CGFloat)leftConstant pinRight:(BOOL)pinRight rightConstant:(CGFloat)rightConstant baseConstant:(CGFloat)baseConstant { diff --git a/MVMCoreUI/Molecules/MoleculeStackView.swift b/MVMCoreUI/Molecules/MoleculeStackView.swift index ab27c481..1c70d6eb 100644 --- a/MVMCoreUI/Molecules/MoleculeStackView.swift +++ b/MVMCoreUI/Molecules/MoleculeStackView.swift @@ -11,7 +11,8 @@ import UIKit public class MoleculeStackView: MFView { var spacingBlock: ((Any) -> UIEdgeInsets)? var moleculesArray: [UIView]? - + var useMargins: Bool = false + public override init(frame: CGRect) { super.init(frame: frame) } @@ -67,9 +68,9 @@ public class MoleculeStackView: MFView { } if let spacingBlock = spacingBlock { - MVMCoreUIStackableViewController.populateView(self, withUIArray: moleculesArray, withSpacingBlock: spacingBlock) + MVMCoreUIStackableViewController.populateView(self, withUIArray: moleculesArray, useMargins: useMargins, withSpacingBlock: spacingBlock) } else { - MVMCoreUIStackableViewController.populateView(self, withUIArray: moleculesArray) { (object) -> UIEdgeInsets in + MVMCoreUIStackableViewController.populateView(self, withUIArray: moleculesArray, useMargins: useMargins) { (object) -> UIEdgeInsets in if object as AnyObject? === moleculesArray.first { return UIEdgeInsets.zero } else { diff --git a/MVMCoreUI/Styles/MFStyler.h b/MVMCoreUI/Styles/MFStyler.h index 488a0648..f9626b1f 100644 --- a/MVMCoreUI/Styles/MFStyler.h +++ b/MVMCoreUI/Styles/MFStyler.h @@ -90,6 +90,7 @@ B3 -> Legal + (CGFloat)defaultVerticalPaddingForApplicationWidth; + (CGFloat)defaultHorizontalPaddingForSize:(CGFloat)size; + (CGFloat)defaultVerticalPaddingForSize:(CGFloat)size; ++ (void)setDefaultMarginsForView:(nullable UIView *)view size:(CGFloat)size; //------------------------------------------------- // Returns the fonts for these styles. Scales them as needed by default diff --git a/MVMCoreUI/Styles/MFStyler.m b/MVMCoreUI/Styles/MFStyler.m index 36d04e51..e7f14546 100644 --- a/MVMCoreUI/Styles/MFStyler.m +++ b/MVMCoreUI/Styles/MFStyler.m @@ -12,6 +12,7 @@ #import "UIColor+MFConvenience.h" #import "NSLayoutConstraint+MFConvenience.h" #import "MVMCoreUISplitViewController.h" +@import MVMCore.MVMCoreDispatchUtility; CGFloat const PaddingDefault = 24; CGFloat const PaddingDefaultHorizontalSpacing = 32; @@ -88,6 +89,17 @@ CGFloat const LabelWithInternalButtonLineSpace = 2; return [[MFSizeObject sizeObjectWithScalingStandardSize:PaddingDefaultVerticalSpacing] getValueBasedOnSize:size]; } ++ (void)setDefaultMarginsForView:(nullable UIView *)view size:(CGFloat)size { + [MVMCoreDispatchUtility performBlockOnMainThread:^{ + CGFloat padding = [MFStyler defaultHorizontalPaddingForSize:size]; + if (@available(iOS 11.0, *)) { + view.directionalLayoutMargins = NSDirectionalEdgeInsetsMake(0, padding, 0, padding); + } else { + view.layoutMargins = UIEdgeInsetsMake(0, padding, 0, padding); + } + }]; +} + #pragma mark - 2.0 fonts + (nullable UIFont *)fontH1:(BOOL)genericScaling { From 0a3bd5c8348c67a3b47c95eab847c2932bf5f9c5 Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Thu, 11 Apr 2019 16:58:53 -0400 Subject: [PATCH 18/27] Updated the string analysis of setText to account for scenarios where an HTML tag is passed as a delimiter. Reoriented the design of the tuple. --- .../Atoms/Views/LabelWithInternalButton.swift | 44 ++++++++++--------- 1 file changed, 24 insertions(+), 20 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index 3810294a..a827c40d 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -10,7 +10,7 @@ import MVMCore public typealias ActionBlock = () -> Void -private typealias ActionIndiciesTuple = (startIndex: String.Index?, endIndex: String.Index?, revisedText: String?) +private typealias ActionableStringTuple = (front: String?, middle: String?, end: String?) public typealias ActionObjectDelegate = (NSObjectProtocol & MVMCoreActionDelegateProtocol) public typealias ButtonObjectDelegate = (NSObjectProtocol & ButtonDelegateProtocol) public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProtocol & MVMCoreLoadDelegateProtocol & MVMCorePresentationDelegateProtocol & NSObjectProtocol @@ -381,37 +381,41 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt private func setText(_ text: String?, startTag: String?, endTag: String?) { - let actionRange: ActionIndiciesTuple = rangeOfText(text, startTag: startTag, endTag: endTag) + let actionableTuple: ActionableStringTuple = rangeOfText(text, startTag: startTag, endTag: endTag) - if let revisedText = actionRange.revisedText, let startBraceIndex = actionRange.startIndex, let endBraceIndex = actionRange.endIndex { - - frontText = String(revisedText[revisedText.startIndex.. ActionIndiciesTuple { + private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> ActionableStringTuple { - var fullText = text ?? "" - var actionRange: ActionIndiciesTuple = (startIndex: nil, endIndex: nil, revisedText: nil) + var actionableTuple: ActionableStringTuple = (front: nil, middle: nil, end: nil) - if let leftBrace = startTag, let rightBrace = endTag, fullText.contains(Character(leftBrace)) && fullText.contains(Character(rightBrace)) { - actionRange.startIndex = fullText.firstIndex(of: Character(leftBrace)) - fullText = fullText.replacingOccurrences(of: leftBrace, with: "") + guard let text = text else { return actionableTuple } + + if let leftTag = startTag, text.contains(leftTag) { - actionRange.endIndex = fullText.firstIndex(of: Character(rightBrace)) - fullText = fullText.replacingOccurrences(of: rightBrace, with: "") + let firstHalf = text.components(separatedBy: leftTag) + actionableTuple.front = firstHalf.first + + if let rightTag = endTag, text.contains(rightTag) { + + let secondHalf = firstHalf[1].components(separatedBy: rightTag) + actionableTuple.middle = secondHalf[0] + actionableTuple.end = secondHalf[1] + } } - - actionRange.revisedText = fullText - return actionRange + + return actionableTuple } @objc public func setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) { From db672f1c21a86636ed8d84439a771e4391682c26 Mon Sep 17 00:00:00 2001 From: "Christiano, Kevin" Date: Fri, 12 Apr 2019 09:53:30 -0400 Subject: [PATCH 19/27] Trimming whitespace to prevent double spaces from occurring. --- MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index a827c40d..42661311 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -384,9 +384,9 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt let actionableTuple: ActionableStringTuple = rangeOfText(text, startTag: startTag, endTag: endTag) if let front = actionableTuple.front, let middle = actionableTuple.middle, let end = actionableTuple.end { - frontText = front - actionText = middle - backText = end + frontText = front.trimmingCharacters(in: .whitespaces) + actionText = middle.trimmingCharacters(in: .whitespaces) + backText = end.trimmingCharacters(in: .whitespaces) self.text = getTextFromStringComponents() } else { frontText = text @@ -408,7 +408,6 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt actionableTuple.front = firstHalf.first if let rightTag = endTag, text.contains(rightTag) { - let secondHalf = firstHalf[1].components(separatedBy: rightTag) actionableTuple.middle = secondHalf[0] actionableTuple.end = secondHalf[1] From f1d80adf5727c7959b7cca82c402e1708b80508d Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Fri, 12 Apr 2019 15:32:43 -0400 Subject: [PATCH 20/27] delegate object and simple deprecation --- MVMCoreUI.xcodeproj/project.pbxproj | 4 ++++ MVMCoreUI/BaseControllers/MFViewController.h | 1 + MVMCoreUI/BaseControllers/MFViewController.m | 4 ++++ MVMCoreUI/OtherHandlers/DelegateObject.swift | 18 ++++++++++++++++++ .../OtherHandlers/MVMCoreUILoggingHandler.h | 1 - MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.h | 1 - MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.h | 1 + 7 files changed, 28 insertions(+), 2 deletions(-) create mode 100644 MVMCoreUI/OtherHandlers/DelegateObject.swift diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 8a2e4453..dea12c71 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -157,6 +157,7 @@ D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; }; D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */; }; + D2E1FADB2260D3D200AEFD8C /* DelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* DelegateObject.swift */; }; DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; }; DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; }; DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretButton.swift */; }; @@ -317,6 +318,7 @@ D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerViewController.swift; sourceTree = ""; }; D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewControllerMappingObject.h; sourceTree = ""; }; D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIViewControllerMappingObject.m; sourceTree = ""; }; + D2E1FADA2260D3D200AEFD8C /* DelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DelegateObject.swift; sourceTree = ""; }; DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = ""; }; DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = ""; }; DBC4391A224421A0001AB423 /* CaretButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretButton.swift; sourceTree = ""; }; @@ -634,6 +636,7 @@ D29DF27021E79B2C003B2FB9 /* OtherHandlers */ = { isa = PBXGroup; children = ( + D2E1FADA2260D3D200AEFD8C /* DelegateObject.swift */, D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */, D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */, D29DF27721E7A533003B2FB9 /* MVMCoreUISession.h */, @@ -865,6 +868,7 @@ D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */, DBC4391922442197001AB423 /* DashLine.swift in Sources */, D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */, + D2E1FADB2260D3D200AEFD8C /* DelegateObject.swift in Sources */, D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */, D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */, D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */, diff --git a/MVMCoreUI/BaseControllers/MFViewController.h b/MVMCoreUI/BaseControllers/MFViewController.h index 8d5c6678..8c1d5766 100644 --- a/MVMCoreUI/BaseControllers/MFViewController.h +++ b/MVMCoreUI/BaseControllers/MFViewController.h @@ -31,6 +31,7 @@ @class MainMenuViewController; @class MVMCoreUITabBarPageControlViewController; @class MVMAnimationManager; +@class DelegateObject; @interface MFViewController : UIViewController diff --git a/MVMCoreUI/BaseControllers/MFViewController.m b/MVMCoreUI/BaseControllers/MFViewController.m index c4ee3756..6b27c7d9 100644 --- a/MVMCoreUI/BaseControllers/MFViewController.m +++ b/MVMCoreUI/BaseControllers/MFViewController.m @@ -180,6 +180,10 @@ return YES; } +- (nullable DelegateObject *)delegateObject { + return [MVMCoreUIDelegateObject createWithDelegateForAll:self]; +} + #pragma mark - Response Handling - (void)observeForResponseJSONUpdates { diff --git a/MVMCoreUI/OtherHandlers/DelegateObject.swift b/MVMCoreUI/OtherHandlers/DelegateObject.swift new file mode 100644 index 00000000..e6c13dd5 --- /dev/null +++ b/MVMCoreUI/OtherHandlers/DelegateObject.swift @@ -0,0 +1,18 @@ +// +// DelegateObject.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 4/12/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objc(MVMCoreUIDelegateObject) +open class DelegateObject: MVMCore.DelegateObject { + public weak var formValidationProtocol: FormValidationProtocol? + + open override func setAll(withDelegate delegate: Any) { + formValidationProtocol = delegate as? FormValidationProtocol + } +} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUILoggingHandler.h b/MVMCoreUI/OtherHandlers/MVMCoreUILoggingHandler.h index 56bb60a2..003d67f8 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUILoggingHandler.h +++ b/MVMCoreUI/OtherHandlers/MVMCoreUILoggingHandler.h @@ -7,7 +7,6 @@ // @import MVMCore.MVMCoreLoggingHandler; -@class MVMCoreTopAlertObject; @class MFViewController; NS_ASSUME_NONNULL_BEGIN diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.h b/MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.h index 9391356c..46b392b7 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.h +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.h @@ -10,7 +10,6 @@ #import #import -@class MVMCoreTopAlertObject; @class MFCustomButton; @interface MVMCoreUITopAlertBaseView : MFView diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.h b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.h index 6ebd1026..50dd9b26 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.h +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.h @@ -11,6 +11,7 @@ #import @class PrimaryButton; +@class MVMCoreTopAlertObject; @interface MVMCoreUITopAlertMainView : MVMCoreUITopAlertBaseView From aa4da8f74f8cc4951cf6859d8fc3b8a828ce3de0 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 15 Apr 2019 11:14:29 -0400 Subject: [PATCH 21/27] deprecating --- MVMCoreUI/Atoms/Buttons/CaretButton.swift | 4 +- MVMCoreUI/Atoms/Buttons/MFCustomButton.h | 17 +++-- MVMCoreUI/Atoms/Buttons/MFCustomButton.m | 71 ++++++++++++++------ MVMCoreUI/OtherHandlers/DelegateObject.swift | 4 +- 4 files changed, 65 insertions(+), 31 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/CaretButton.swift b/MVMCoreUI/Atoms/Buttons/CaretButton.swift index 7d67afb1..72c04900 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretButton.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretButton.swift @@ -106,14 +106,14 @@ open class CaretButton: MFCustomButton { //------------------------------------------------------ // Default values for view. - @objc open override func setAsMolecule() { + @objc open func setAsMolecule() { backgroundColor = .clear setTitleColor(enabledColor, for: .normal) setTitleColor(disabledColor, for: .disabled) } - @objc override open func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) { + @objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) { setWithActionMap(json, delegate: delegate as? (MVMCoreActionDelegateProtocol & NSObjectProtocol), additionalData: additionalData) guard let dictionary = json else { return } diff --git a/MVMCoreUI/Atoms/Buttons/MFCustomButton.h b/MVMCoreUI/Atoms/Buttons/MFCustomButton.h index 21236e70..47ac89e4 100644 --- a/MVMCoreUI/Atoms/Buttons/MFCustomButton.h +++ b/MVMCoreUI/Atoms/Buttons/MFCustomButton.h @@ -11,14 +11,14 @@ #import #import #import -@import MVMCore.MVMCoreViewProtocol; +@class MVMCoreUIDelegateObject; typedef void (^ButtonTapBlock)(id _Nonnull sender); extern CGFloat const CloseButtonHeight; extern CGFloat const CloseButtonWidth; -@interface MFCustomButton : UIButton +@interface MFCustomButton : UIButton @property (nullable, nonatomic, strong) NSDictionary *actionMap; @property (nullable, nonatomic, weak) id buttonDelegate; @@ -28,14 +28,19 @@ extern CGFloat const CloseButtonWidth; - (void)addBlock:(nonnull ButtonTapBlock)buttonTapBlock forControlEvents:(UIControlEvents)event; // Sets up the button with the passed in action map. Will set the title and set the action to use the action handler. -- (void)setWithActionMap:(nullable NSDictionary *)actionMap delegate:(nullable NSObject *)delegate additionalData:(nullable NSDictionary *)additionalData; - -// Sets up the button with the passed in action map. Will set the title and set the action to use the action handler. Also pass in the button delegate -- (void)setWithActionMap:(nullable NSDictionary *)actionMap actionDelegate:(nullable NSObject *)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id )buttonDelegate; +- (void)setWithActionMap:(nullable NSDictionary *)actionMap delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; //accessibility - (void)addAccessibilityForCameraControl; - (nonnull UIAccessibilityCustomAction *)accessibilityCustomAction; +#pragma mark - Deprecated + +// Sets up the button with the passed in action map. Will set the title and set the action to use the action handler. +- (void)setWithActionMap:(nullable NSDictionary *)actionMap delegate:(nullable NSObject *)delegate additionalData:(nullable NSDictionary *)additionalData __deprecated; + +// Sets up the button with the passed in action map. Will set the title and set the action to use the action handler. Also pass in the button delegate +- (void)setWithActionMap:(nullable NSDictionary *)actionMap actionDelegate:(nullable NSObject *)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id )buttonDelegate __deprecated; + @end diff --git a/MVMCoreUI/Atoms/Buttons/MFCustomButton.m b/MVMCoreUI/Atoms/Buttons/MFCustomButton.m index 0a78856c..45daebcc 100644 --- a/MVMCoreUI/Atoms/Buttons/MFCustomButton.m +++ b/MVMCoreUI/Atoms/Buttons/MFCustomButton.m @@ -13,6 +13,7 @@ @import MVMCore.NSDictionary_MFConvenience; #import "MVMCoreUIUtility.h" #import "MVMCoreUIConstants.h" +#import CGFloat const CloseButtonHeight = 40.0f; CGFloat const CloseButtonWidth = 40.0f; @@ -37,6 +38,52 @@ CGFloat const CloseButtonWidth = 40.0f; } } +- (void)setWithActionMap:(nullable NSDictionary *)actionMap delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { + + self.actionMap = actionMap; + self.titleLabel.numberOfLines = 0; + self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; + [self setTitle:[actionMap stringForKey:KeyTitle] forState:UIControlStateNormal]; + + [self setEnabled:![actionMap[KeyDisableButton]boolValue]]; + + self.buttonDelegate = delegateObject.buttonDelegate; + __weak MFCustomButton *weakSelf = self; + [self addBlock:^(id _Nonnull sender) { + + BOOL performAction = YES; + if (weakSelf.buttonDelegate && [weakSelf.buttonDelegate respondsToSelector:@selector(button:shouldPerformActionWithMap:additionalData:)]) { + performAction = [weakSelf.buttonDelegate button:weakSelf shouldPerformActionWithMap:actionMap additionalData:additionalData]; + } + + if (performAction) { + [[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:actionMap additionalData:additionalData delegateObject:delegateObject]; + } + } forControlEvents:UIControlEventTouchUpInside]; +} + +//accessibility +-(void)addAccessibilityForCameraControl{ + self.accessibilityLabel = [MVMCoreUIUtility hardcodedStringWithKey:@"AccCameraButton"]; + self.accessibilityHint = [MVMCoreUIUtility hardcodedStringWithKey:@"AccCameraHint"]; + self.accessibilityTraits = UIAccessibilityTraitNone; +} + + +- (UIAccessibilityCustomAction *)accessibilityCustomAction { + NSString *name = self.accessibilityLabel ?: self.titleLabel.text; + return [[UIAccessibilityCustomAction alloc] initWithName:name target:self selector:@selector(performAccessibilityAction:)]; +} + +- (BOOL)performAccessibilityAction:(UIAccessibilityCustomAction *)action { + if (self.buttonTapBlock) { + self.buttonTapBlock(self); + } + return YES; +} + +#pragma mark - Deprecated + - (void)setWithActionMap:(nullable NSDictionary *)actionMap delegate:(nullable NSObject *)delegate additionalData:(nullable NSDictionary *)additionalData { self.actionMap = actionMap; @@ -53,11 +100,11 @@ CGFloat const CloseButtonWidth = 40.0f; } - (void)setWithActionMap:(nullable NSDictionary *)actionMap actionDelegate:(nullable NSObject *)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id )buttonDelegate { - + if (!buttonDelegate) { [self setWithActionMap:actionMap delegate:actionDelegate additionalData:additionalData]; } else { - + self.actionMap = actionMap; self.titleLabel.numberOfLines = 0; self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping; @@ -86,24 +133,4 @@ CGFloat const CloseButtonWidth = 40.0f; } } -//accessibility --(void)addAccessibilityForCameraControl{ - self.accessibilityLabel = [MVMCoreUIUtility hardcodedStringWithKey:@"AccCameraButton"]; - self.accessibilityHint = [MVMCoreUIUtility hardcodedStringWithKey:@"AccCameraHint"]; - self.accessibilityTraits = UIAccessibilityTraitNone; -} - - -- (UIAccessibilityCustomAction *)accessibilityCustomAction { - NSString *name = self.accessibilityLabel ?: self.titleLabel.text; - return [[UIAccessibilityCustomAction alloc] initWithName:name target:self selector:@selector(performAccessibilityAction:)]; -} - -- (BOOL)performAccessibilityAction:(UIAccessibilityCustomAction *)action { - if (self.buttonTapBlock) { - self.buttonTapBlock(self); - } - return YES; -} - @end diff --git a/MVMCoreUI/OtherHandlers/DelegateObject.swift b/MVMCoreUI/OtherHandlers/DelegateObject.swift index e6c13dd5..d7a2ac65 100644 --- a/MVMCoreUI/OtherHandlers/DelegateObject.swift +++ b/MVMCoreUI/OtherHandlers/DelegateObject.swift @@ -11,8 +11,10 @@ import UIKit @objc(MVMCoreUIDelegateObject) open class DelegateObject: MVMCore.DelegateObject { public weak var formValidationProtocol: FormValidationProtocol? - + public weak var buttonDelegate: ButtonDelegateProtocol? + open override func setAll(withDelegate delegate: Any) { formValidationProtocol = delegate as? FormValidationProtocol + buttonDelegate = delegate as? ButtonDelegateProtocol } } From ad3c0f90b4db607c2dcf489a3f8f2b2c7686d3a3 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 15 Apr 2019 11:46:26 -0400 Subject: [PATCH 22/27] molecule view changes --- MVMCoreUI/Atoms/Views/MFLabel.m | 6 +++--- MVMCoreUI/Atoms/Views/MFView.m | 2 +- MVMCoreUI/Molecules/ButtonView.swift | 6 +++--- MVMCoreUI/Molecules/MVMCoreUIMoleculeViewProtocol.h | 3 ++- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/MVMCoreUI/Atoms/Views/MFLabel.m b/MVMCoreUI/Atoms/Views/MFLabel.m index 66b434e5..3857cd8d 100644 --- a/MVMCoreUI/Atoms/Views/MFLabel.m +++ b/MVMCoreUI/Atoms/Views/MFLabel.m @@ -170,7 +170,7 @@ } } -+ (void)setUILabel:(nullable UILabel *)label withJSON:(nullable NSDictionary *)json delegate:(nullable NSObject *)delegate additionalData:(nullable NSDictionary *)additionalData { ++ (void)setUILabel:(nullable UILabel *)label withJSON:(nullable NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { if (label) { label.text = [json string:KeyText]; [self setLabel:label withHTML:[json string:@"html"]]; @@ -232,8 +232,8 @@ } } -- (void)setWithJSON:(NSDictionary *)json delegate:(NSObject *)delegate additionalData:(NSDictionary *)additionalData { - [MFLabel setUILabel:self withJSON:json delegate:delegate additionalData:additionalData]; +- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { + [MFLabel setUILabel:self withJSON:json delegateObject:delegateObject additionalData:additionalData]; self.originalAttributedString = self.attributedText; } diff --git a/MVMCoreUI/Atoms/Views/MFView.m b/MVMCoreUI/Atoms/Views/MFView.m index 1ab4cda1..6c0f8309 100644 --- a/MVMCoreUI/Atoms/Views/MFView.m +++ b/MVMCoreUI/Atoms/Views/MFView.m @@ -43,7 +43,7 @@ #pragma mark - MVMCoreUIMoleculeViewProtocol -- (void)setWithJSON:(NSDictionary *)json delegate:(NSObject *)delegate additionalData:(nullable NSDictionary *)additionalData { +- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { self.json = json; } diff --git a/MVMCoreUI/Molecules/ButtonView.swift b/MVMCoreUI/Molecules/ButtonView.swift index f48044dd..5391640c 100644 --- a/MVMCoreUI/Molecules/ButtonView.swift +++ b/MVMCoreUI/Molecules/ButtonView.swift @@ -58,9 +58,9 @@ import UIKit primaryButton?.setAsMolecule() } - open override func setWithJSON(_ json: [AnyHashable : Any]?, delegate: NSObject?, additionalData: [AnyHashable : Any]?) { - super.setWithJSON(json, delegate: delegate, additionalData: additionalData) - primaryButton?.setWithJSON(json, delegate: delegate, additionalData: additionalData) + open override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUI.DelegateObject?, additionalData: [AnyHashable : Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + primaryButton?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) } // MARK: - Constraining diff --git a/MVMCoreUI/Molecules/MVMCoreUIMoleculeViewProtocol.h b/MVMCoreUI/Molecules/MVMCoreUIMoleculeViewProtocol.h index 3dd8de67..19cc1e21 100644 --- a/MVMCoreUI/Molecules/MVMCoreUIMoleculeViewProtocol.h +++ b/MVMCoreUI/Molecules/MVMCoreUIMoleculeViewProtocol.h @@ -7,11 +7,12 @@ // #import +@class MVMCoreUIDelegateObject; @protocol MVMCoreUIMoleculeViewProtocol // Sets up the ui based on the json -- (void)setWithJSON:(nullable NSDictionary *)json delegate:(nullable NSObject *)delegate additionalData:(nullable NSDictionary *)additionalData; +- (void)setWithJSON:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; @optional From 5ebcba15fa808f214f5ebdfced5d6a2150d34a2b Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 15 Apr 2019 12:59:27 -0400 Subject: [PATCH 23/27] molecule delegate object --- MVMCoreUI.xcodeproj/project.pbxproj | 8 +- MVMCoreUI/Atoms/Buttons/CaretButton.swift | 4 +- MVMCoreUI/Atoms/Buttons/MFCustomButton.h | 4 +- MVMCoreUI/Atoms/Buttons/MFCustomButton.m | 6 +- MVMCoreUI/Atoms/Views/CaretView.swift | 7 +- MVMCoreUI/Atoms/Views/DashLine.swift | 4 +- MVMCoreUI/Atoms/Views/LabelView.m | 6 +- .../Atoms/Views/LabelWithInternalButton.swift | 3 +- MVMCoreUI/Atoms/Views/MFLabel.m | 4 +- MVMCoreUI/Atoms/Views/MFLoadImageView.swift | 4 +- MVMCoreUI/Atoms/Views/MFView.m | 3 +- MVMCoreUI/Atoms/Views/SeparatorView.m | 4 +- MVMCoreUI/Molecules/ButtonView.swift | 6 +- .../Molecules/MVMCoreUIMoleculeViewProtocol.h | 4 +- MVMCoreUI/Molecules/MoleculeStackView.swift | 14 ++-- MVMCoreUI/Molecules/StandardFooterView.swift | 8 +- MVMCoreUI/Molecules/StandardHeaderView.swift | 10 +-- MVMCoreUI/Molecules/TwoButtonView.swift | 82 ++++++++++--------- ...ct.swift => MVMCoreUIDelegateObject.swift} | 3 +- .../MVMCoreUIMoleculeMappingObject.h | 3 +- .../MVMCoreUIMoleculeMappingObject.m | 4 +- .../MoleculeStackCenteredTemplate.swift | 6 +- .../Templates/MoleculeStackTemplate.swift | 6 +- 23 files changed, 106 insertions(+), 97 deletions(-) rename MVMCoreUI/OtherHandlers/{DelegateObject.swift => MVMCoreUIDelegateObject.swift} (85%) diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index dea12c71..1f3e1d53 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -157,7 +157,7 @@ D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; }; D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */; }; - D2E1FADB2260D3D200AEFD8C /* DelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* DelegateObject.swift */; }; + D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */; }; DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; }; DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; }; DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretButton.swift */; }; @@ -318,7 +318,7 @@ D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerViewController.swift; sourceTree = ""; }; D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewControllerMappingObject.h; sourceTree = ""; }; D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIViewControllerMappingObject.m; sourceTree = ""; }; - D2E1FADA2260D3D200AEFD8C /* DelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DelegateObject.swift; sourceTree = ""; }; + D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUIDelegateObject.swift; sourceTree = ""; }; DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = ""; }; DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = ""; }; DBC4391A224421A0001AB423 /* CaretButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretButton.swift; sourceTree = ""; }; @@ -636,7 +636,7 @@ D29DF27021E79B2C003B2FB9 /* OtherHandlers */ = { isa = PBXGroup; children = ( - D2E1FADA2260D3D200AEFD8C /* DelegateObject.swift */, + D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */, D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */, D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */, D29DF27721E7A533003B2FB9 /* MVMCoreUISession.h */, @@ -868,7 +868,7 @@ D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */, DBC4391922442197001AB423 /* DashLine.swift in Sources */, D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */, - D2E1FADB2260D3D200AEFD8C /* DelegateObject.swift in Sources */, + D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */, D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */, D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */, D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/CaretButton.swift b/MVMCoreUI/Atoms/Buttons/CaretButton.swift index 72c04900..0849ed26 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretButton.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretButton.swift @@ -113,8 +113,8 @@ open class CaretButton: MFCustomButton { setTitleColor(disabledColor, for: .disabled) } - @objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) { - setWithActionMap(json, delegate: delegate as? (MVMCoreActionDelegateProtocol & NSObjectProtocol), additionalData: additionalData) + open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { + setWithActionMap(json, delegateObject: delegateObject, additionalData: additionalData) guard let dictionary = json else { return } diff --git a/MVMCoreUI/Atoms/Buttons/MFCustomButton.h b/MVMCoreUI/Atoms/Buttons/MFCustomButton.h index 47ac89e4..9d08883d 100644 --- a/MVMCoreUI/Atoms/Buttons/MFCustomButton.h +++ b/MVMCoreUI/Atoms/Buttons/MFCustomButton.h @@ -11,7 +11,7 @@ #import #import #import -@class MVMCoreUIDelegateObject; +@class DelegateObject; typedef void (^ButtonTapBlock)(id _Nonnull sender); @@ -28,7 +28,7 @@ extern CGFloat const CloseButtonWidth; - (void)addBlock:(nonnull ButtonTapBlock)buttonTapBlock forControlEvents:(UIControlEvents)event; // Sets up the button with the passed in action map. Will set the title and set the action to use the action handler. -- (void)setWithActionMap:(nullable NSDictionary *)actionMap delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; +- (void)setWithActionMap:(nullable NSDictionary *)actionMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; //accessibility - (void)addAccessibilityForCameraControl; diff --git a/MVMCoreUI/Atoms/Buttons/MFCustomButton.m b/MVMCoreUI/Atoms/Buttons/MFCustomButton.m index 45daebcc..1610f42b 100644 --- a/MVMCoreUI/Atoms/Buttons/MFCustomButton.m +++ b/MVMCoreUI/Atoms/Buttons/MFCustomButton.m @@ -38,7 +38,7 @@ CGFloat const CloseButtonWidth = 40.0f; } } -- (void)setWithActionMap:(nullable NSDictionary *)actionMap delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { +- (void)setWithActionMap:(nullable NSDictionary *)actionMap delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { self.actionMap = actionMap; self.titleLabel.numberOfLines = 0; @@ -47,7 +47,9 @@ CGFloat const CloseButtonWidth = 40.0f; [self setEnabled:![actionMap[KeyDisableButton]boolValue]]; - self.buttonDelegate = delegateObject.buttonDelegate; + if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { + self.buttonDelegate = ((MVMCoreUIDelegateObject *)delegateObject).buttonDelegate; + } __weak MFCustomButton *weakSelf = self; [self addBlock:^(id _Nonnull sender) { diff --git a/MVMCoreUI/Atoms/Views/CaretView.swift b/MVMCoreUI/Atoms/Views/CaretView.swift index 563dc2d1..eb3a4c4b 100644 --- a/MVMCoreUI/Atoms/Views/CaretView.swift +++ b/MVMCoreUI/Atoms/Views/CaretView.swift @@ -94,10 +94,9 @@ open class CaretView: MFView { defaultState() } - - @objc override open func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) { - super.setWithJSON(json, delegate: delegate, additionalData: additionalData) - + + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) // Configure class properties with JSON values guard let jsonDictionary = json else { return } diff --git a/MVMCoreUI/Atoms/Views/DashLine.swift b/MVMCoreUI/Atoms/Views/DashLine.swift index 9b3e7f52..82c05b27 100644 --- a/MVMCoreUI/Atoms/Views/DashLine.swift +++ b/MVMCoreUI/Atoms/Views/DashLine.swift @@ -68,8 +68,8 @@ open class DashLine: MFView { isHidden = false } - @objc override open func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) { - super.setWithJSON(json, delegate: delegate, additionalData: additionalData) + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) // Configure class properties with JSON values guard let jsonDictionary = json else { return } diff --git a/MVMCoreUI/Atoms/Views/LabelView.m b/MVMCoreUI/Atoms/Views/LabelView.m index f1d7b2f0..15915cec 100644 --- a/MVMCoreUI/Atoms/Views/LabelView.m +++ b/MVMCoreUI/Atoms/Views/LabelView.m @@ -72,9 +72,9 @@ } } -- (void)setWithJSON:(NSDictionary *)json delegate:(NSObject *)delegate additionalData:(NSDictionary *)additionalData { - [super setWithJSON:json delegate:delegate additionalData:additionalData]; - [self.label setWithJSON:json delegate:delegate additionalData:additionalData]; +- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { + [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; + [self.label setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; } - (void)alignLeft { diff --git a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift index 3810294a..b749b41f 100644 --- a/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift +++ b/MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift @@ -553,8 +553,7 @@ extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol { } - @objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) { - + @objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { // Configure class properties with JSON values guard let dictionary = json else { return } diff --git a/MVMCoreUI/Atoms/Views/MFLabel.m b/MVMCoreUI/Atoms/Views/MFLabel.m index 3857cd8d..5fb19037 100644 --- a/MVMCoreUI/Atoms/Views/MFLabel.m +++ b/MVMCoreUI/Atoms/Views/MFLabel.m @@ -170,7 +170,7 @@ } } -+ (void)setUILabel:(nullable UILabel *)label withJSON:(nullable NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { ++ (void)setUILabel:(nullable UILabel *)label withJSON:(nullable NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData { if (label) { label.text = [json string:KeyText]; [self setLabel:label withHTML:[json string:@"html"]]; @@ -232,7 +232,7 @@ } } -- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { +- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { [MFLabel setUILabel:self withJSON:json delegateObject:delegateObject additionalData:additionalData]; self.originalAttributedString = self.attributedText; } diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift index 257fe041..b08dc249 100644 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift @@ -203,8 +203,8 @@ import UIKit } // MARK: - MVMCoreUIMoleculeViewProtocol functions - open override func setWithJSON(_ json: [AnyHashable : Any]?, delegate: NSObject?, additionalData: [AnyHashable : Any]?) { - super.setWithJSON(json, delegate: delegate, additionalData: additionalData) + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) { backgroundColor = UIColor.mfGet(forHex: backgroundColorString) } diff --git a/MVMCoreUI/Atoms/Views/MFView.m b/MVMCoreUI/Atoms/Views/MFView.m index 6c0f8309..4bd73485 100644 --- a/MVMCoreUI/Atoms/Views/MFView.m +++ b/MVMCoreUI/Atoms/Views/MFView.m @@ -7,6 +7,7 @@ // #import "MFView.h" +@import MVMCore.Swift; @implementation MFView @@ -43,7 +44,7 @@ #pragma mark - MVMCoreUIMoleculeViewProtocol -- (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { +- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { self.json = json; } diff --git a/MVMCoreUI/Atoms/Views/SeparatorView.m b/MVMCoreUI/Atoms/Views/SeparatorView.m index 73cd84ff..95fe8bb8 100644 --- a/MVMCoreUI/Atoms/Views/SeparatorView.m +++ b/MVMCoreUI/Atoms/Views/SeparatorView.m @@ -95,8 +95,8 @@ } } -- (void)setWithJSON:(NSDictionary *)json delegate:(NSObject *)delegate additionalData:(NSDictionary *)additionalData { - [super setWithJSON:json delegate:delegate additionalData:additionalData]; +- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { + [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; if (json) { self.hidden = NO; NSString *type = [json string:KeyType]; diff --git a/MVMCoreUI/Molecules/ButtonView.swift b/MVMCoreUI/Molecules/ButtonView.swift index 5391640c..8958887c 100644 --- a/MVMCoreUI/Molecules/ButtonView.swift +++ b/MVMCoreUI/Molecules/ButtonView.swift @@ -33,9 +33,9 @@ import UIKit primaryButton?.isEnabled = enabled } - public init(withJSON json: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate: NSObject?, buttonDelegate: Any?) { + public init(withJSON json: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) { super.init(frame: .zero) - setWithJSON(json, delegate: actionDelegate, additionalData: additionalData) + setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) } // MARK: - MVMCoreViewProtocol @@ -58,7 +58,7 @@ import UIKit primaryButton?.setAsMolecule() } - open override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUI.DelegateObject?, additionalData: [AnyHashable : Any]?) { + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) primaryButton?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) } diff --git a/MVMCoreUI/Molecules/MVMCoreUIMoleculeViewProtocol.h b/MVMCoreUI/Molecules/MVMCoreUIMoleculeViewProtocol.h index 19cc1e21..ac92e0a1 100644 --- a/MVMCoreUI/Molecules/MVMCoreUIMoleculeViewProtocol.h +++ b/MVMCoreUI/Molecules/MVMCoreUIMoleculeViewProtocol.h @@ -7,12 +7,12 @@ // #import -@class MVMCoreUIDelegateObject; +@class DelegateObject; @protocol MVMCoreUIMoleculeViewProtocol // Sets up the ui based on the json -- (void)setWithJSON:(nullable NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; +- (void)setWithJSON:(nullable NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; @optional diff --git a/MVMCoreUI/Molecules/MoleculeStackView.swift b/MVMCoreUI/Molecules/MoleculeStackView.swift index 1c70d6eb..57b0108c 100644 --- a/MVMCoreUI/Molecules/MoleculeStackView.swift +++ b/MVMCoreUI/Molecules/MoleculeStackView.swift @@ -17,13 +17,13 @@ public class MoleculeStackView: MFView { super.init(frame: frame) } - public init(withJSON json: [AnyHashable : Any]?, delegate: NSObject?, additionalData: [AnyHashable : Any]?) { + public init(withJSON json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) { super.init(frame: CGRect.zero) - setWithJSON(json, delegate: delegate, additionalData: additionalData) + setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) } - public convenience init(withJSON json: [AnyHashable : Any]?, delegate: NSObject?, spacingBlock: ((Any) -> UIEdgeInsets)?) { - self.init(withJSON: json, delegate: delegate, additionalData: nil) + public convenience init(withJSON json: [AnyHashable: Any]?, delegateObject: DelegateObject?, spacingBlock: ((Any) -> UIEdgeInsets)?) { + self.init(withJSON: json, delegateObject: delegateObject, additionalData: nil) self.spacingBlock = spacingBlock } @@ -48,8 +48,8 @@ public class MoleculeStackView: MFView { } } - public override func setWithJSON(_ json: [AnyHashable : Any]?, delegate: NSObject?, additionalData: [AnyHashable : Any]?) { - super.setWithJSON(json, delegate: delegate, additionalData: additionalData) + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) guard let molecules = json?.arrayForKey("molecules") as? [[String: Any]] else { return } @@ -58,7 +58,7 @@ public class MoleculeStackView: MFView { var moleculesArray = [] as [UIView] for moleculeJSON in molecules { if let name = moleculeJSON.optionalStringForKey("moleculeName"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForName(name) { - molecule.setWithJSON(moleculeJSON, delegate: delegate, additionalData: additionalData) + molecule.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) moleculesArray.append(molecule) } } diff --git a/MVMCoreUI/Molecules/StandardFooterView.swift b/MVMCoreUI/Molecules/StandardFooterView.swift index 99880b9b..a170d023 100644 --- a/MVMCoreUI/Molecules/StandardFooterView.swift +++ b/MVMCoreUI/Molecules/StandardFooterView.swift @@ -103,12 +103,12 @@ public class StandardFooterView: ViewConstrainingView { rightConstraintTextButton?.constant = constant } - public override func setWithJSON(_ json: [AnyHashable : Any]?, delegate: NSObject?, additionalData: [AnyHashable : Any]?) { - super.setWithJSON(json, delegate: delegate, additionalData: additionalData) + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) if let colorString = json?.optionalStringForKey(KeyBackgroundColor) { backgroundColor = .mfGet(forHex: colorString) } - twoButtonView.setWithJSON(json?.optionalDictionaryForKey("twoButtonView"), delegate: delegate, additionalData: additionalData) - textButton.setWithJSON(json?.optionalDictionaryForKey("textButton"), delegate: delegate, additionalData: additionalData) + twoButtonView.setWithJSON(json?.optionalDictionaryForKey("twoButtonView"), delegateObject: delegateObject, additionalData: additionalData) + textButton.setWithJSON(json?.optionalDictionaryForKey("textButton"), delegateObject: delegateObject, additionalData: additionalData) } } diff --git a/MVMCoreUI/Molecules/StandardHeaderView.swift b/MVMCoreUI/Molecules/StandardHeaderView.swift index 8c05a4c6..488e31c1 100644 --- a/MVMCoreUI/Molecules/StandardHeaderView.swift +++ b/MVMCoreUI/Molecules/StandardHeaderView.swift @@ -110,8 +110,8 @@ public class StandardHeaderView: ViewConstrainingView { separatorView?.rightPin?.constant = constant } - public override func setWithJSON(_ json: [AnyHashable : Any]?, delegate: NSObject?, additionalData: [AnyHashable : Any]?) { - super.setWithJSON(json, delegate: delegate, additionalData: additionalData) + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) if let colorString = json?.optionalStringForKey(KeyBackgroundColor) { backgroundColor = .mfGet(forHex: colorString) } @@ -123,11 +123,11 @@ public class StandardHeaderView: ViewConstrainingView { } let headlineJSON = json?.optionalDictionaryForKey("headline") - headlineLabel.setWithJSON(headlineJSON, delegate: delegate, additionalData: additionalData) + headlineLabel.setWithJSON(headlineJSON, delegateObject: delegateObject, additionalData: additionalData) let bodyJSON = json?.optionalDictionaryForKey("body") - messageLabel.setWithJSON(bodyJSON, delegate: delegate, additionalData: additionalData) + messageLabel.setWithJSON(bodyJSON, delegateObject: delegateObject, additionalData: additionalData) let separatorJSON = json?.optionalDictionaryForKey("separator") - separatorView?.setWithJSON(separatorJSON, delegate: delegate, additionalData: additionalData) + separatorView?.setWithJSON(separatorJSON, delegateObject: delegateObject, additionalData: additionalData) if separatorView?.isHidden ?? true { bottomPin?.constant = 0 diff --git a/MVMCoreUI/Molecules/TwoButtonView.swift b/MVMCoreUI/Molecules/TwoButtonView.swift index c56d82bf..58586126 100644 --- a/MVMCoreUI/Molecules/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/TwoButtonView.swift @@ -39,14 +39,14 @@ import UIKit } // MARK: - MVMCoreUIMoleculeViewProtocol - open override func setWithJSON(_ json: [AnyHashable : Any]?, delegate: NSObject?, additionalData: [AnyHashable : Any]?) { - super.setWithJSON(json, delegate: delegate, additionalData: additionalData) + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) { backgroundColor = UIColor.mfGet(forHex: backgroundColorString) } let primaryButtonMap = json?.optionalDictionaryForKey("primaryButton") let secondaryButtonMap = json?.optionalDictionaryForKey("secondaryButton") - set(primaryButtonJSON: primaryButtonMap, secondaryButtonJSON: secondaryButtonMap, actionDelegate: delegate, additionalData: additionalData, buttonDelegate: delegate) + set(primaryButtonJSON: primaryButtonMap, secondaryButtonJSON: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) } // MARK: - Constraining @@ -142,33 +142,14 @@ import UIKit } } - open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { + open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON, legacy: false) setDefaultCustom() - primaryButton?.setWithJSON(primaryButtonJSON, delegate: actionDelegate as? NSObject, additionalData: additionalData) - secondaryButton?.setWithJSON(secondaryButtonJSON, delegate: actionDelegate as? NSObject, additionalData: additionalData) + primaryButton?.setWithJSON(primaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData) + secondaryButton?.setWithJSON(secondaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData) } // MARK: - Legacy - open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { - let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton) - let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton) - setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) - } - - open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { - setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, legacy: true) - if primaryButtonMap != nil, secondaryButtonMap != nil { - primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) - secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) - } else if primaryButtonMap != nil { - primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) - primaryButton?.bordered = false - } else if secondaryButtonMap != nil { - primaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) - primaryButton?.bordered = true - } - } public convenience init(buttonSmall small: Bool, enabled: Bool) { self.init() @@ -178,18 +159,6 @@ import UIKit primaryButton?.isEnabled = enabled } - public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: AnyHashable]?, buttonDelegate: Any?) { - self.init() - setup(withButtonMap: buttonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) - primaryButton?.setAsSmall(small) - secondaryButton?.setAsSmall(small) - } - - public convenience init(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { - self.init() - setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) - } - public func hidePrimaryLeftButton() { guard let secondaryButton = secondaryButton, !secondaryButton.isHidden else { return @@ -229,3 +198,42 @@ import UIKit secondaryButton?.isHidden = true } } + +// MARK: - Deprecate +extension TwoButtonView { + @available(*, deprecated) + open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { + setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, legacy: true) + if primaryButtonMap != nil, secondaryButtonMap != nil { + primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) + secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) + } else if primaryButtonMap != nil { + primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) + primaryButton?.bordered = false + } else if secondaryButtonMap != nil { + primaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol) + primaryButton?.bordered = true + } + } + + @available(*, deprecated) + open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { + let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton) + let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton) + setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) + } + + @available(*, deprecated) + public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: AnyHashable]?, buttonDelegate: Any?) { + self.init() + setup(withButtonMap: buttonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) + primaryButton?.setAsSmall(small) + secondaryButton?.setAsSmall(small) + } + + @available(*, deprecated) + public convenience init(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) { + self.init() + setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate) + } +} diff --git a/MVMCoreUI/OtherHandlers/DelegateObject.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift similarity index 85% rename from MVMCoreUI/OtherHandlers/DelegateObject.swift rename to MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift index d7a2ac65..91ce13c3 100644 --- a/MVMCoreUI/OtherHandlers/DelegateObject.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift @@ -8,8 +8,7 @@ import UIKit -@objc(MVMCoreUIDelegateObject) -open class DelegateObject: MVMCore.DelegateObject { +open class MVMCoreUIDelegateObject: DelegateObject { public weak var formValidationProtocol: FormValidationProtocol? public weak var buttonDelegate: ButtonDelegateProtocol? diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.h b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.h index 7d229bbe..a79ca208 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.h +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.h @@ -8,6 +8,7 @@ #import #import +@class DelegateObject; @interface MVMCoreUIMoleculeMappingObject : NSObject @@ -19,6 +20,6 @@ // Returns the molecule for the given name. - (nullable UIView *)getMoleculeForName:(nonnull NSString *)name; -- (nullable UIView *)getMoleculeForJSON:(nonnull NSDictionary *)json delegate:(nullable NSObject *)delegate; +- (nullable UIView *)getMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject; @end diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index 0936f9df..c1d7a36d 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -55,13 +55,13 @@ return nil; } -- (nullable UIView *)getMoleculeForJSON:(nonnull NSDictionary *)json delegate:(nullable NSObject *)delegate { +- (nullable UIView *)getMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject { NSString *moleculeName = [json string:@"moleculeName"]; if (!moleculeName) { return nil; } UIView *molecule = [self getMoleculeForName:moleculeName]; - [molecule setWithJSON:json delegate:delegate additionalData:nil]; + [molecule setWithJSON:json delegateObject:delegateObject additionalData:nil]; return molecule; } diff --git a/MVMCoreUI/Templates/MoleculeStackCenteredTemplate.swift b/MVMCoreUI/Templates/MoleculeStackCenteredTemplate.swift index ab7b6dec..bdd187fe 100644 --- a/MVMCoreUI/Templates/MoleculeStackCenteredTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeStackCenteredTemplate.swift @@ -12,13 +12,13 @@ public class MoleculeStackCenteredTemplate: ThreeLayerViewController { public override func viewForMiddle() -> UIView? { let molecule = loadObject?.pageJSON?.optionalDictionaryForKey("moleculeStack") - let moleculeStack = MoleculeStackView(withJSON: molecule, delegate: self, additionalData: nil) + 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()?.getMoleculeForJSON(moleculeJSON, delegate: self) else { + let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForJSON(moleculeJSON, delegateObject: delegateObject()) else { return nil } return molecule @@ -26,7 +26,7 @@ public class MoleculeStackCenteredTemplate: ThreeLayerViewController { override public func viewForBottom() -> UIView? { guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), - let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForJSON(moleculeJSON, delegate: self) else { + let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForJSON(moleculeJSON, delegateObject: delegateObject()) else { return nil } return molecule diff --git a/MVMCoreUI/Templates/MoleculeStackTemplate.swift b/MVMCoreUI/Templates/MoleculeStackTemplate.swift index 2910782d..dfcef277 100644 --- a/MVMCoreUI/Templates/MoleculeStackTemplate.swift +++ b/MVMCoreUI/Templates/MoleculeStackTemplate.swift @@ -16,7 +16,7 @@ public class MoleculeStackTemplate: ThreeLayerViewController { } public override func viewForTop() -> UIView? { - guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForJSON(moleculeJSON, delegate: self) else { + guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForJSON(moleculeJSON, delegateObject: delegateObject()) else { return nil } return molecule @@ -26,11 +26,11 @@ public class MoleculeStackTemplate: ThreeLayerViewController { guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("moleculeStack") else { return nil } - return MoleculeStackView(withJSON: moleculeJSON, delegate: self, additionalData: nil) + return MoleculeStackView(withJSON: moleculeJSON, delegateObject: delegateObject(), additionalData: nil) } override public func viewForBottom() -> UIView? { - guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForJSON(moleculeJSON, delegate: self) else { + guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForJSON(moleculeJSON, delegateObject: delegateObject()) else { return nil } return molecule From 8c19755ba87f42842d1248dda57b2d87daac1906 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 15 Apr 2019 13:31:45 -0400 Subject: [PATCH 24/27] warning fix --- MVMCoreUI/Atoms/Buttons/MFTextButton.m | 4 +-- MVMCoreUI/Atoms/Buttons/PrimaryButton.m | 11 ++++--- MVMCoreUI/Atoms/Views/MFLabel.h | 3 +- MVMCoreUI/BaseControllers/MFViewController.m | 10 +++--- ...MVMCoreUITabBarPageControlViewController.m | 2 +- .../FormValidator+FormParams.swift | 4 +-- ...abelsAndBottomButtonsTableViewController.m | 2 +- .../TopLabelsAndBottomButtonsViewController.m | 2 +- MVMCoreUI/Molecules/TwoButtonView.swift | 31 +++++++++++++++++++ 9 files changed, 51 insertions(+), 18 deletions(-) diff --git a/MVMCoreUI/Atoms/Buttons/MFTextButton.m b/MVMCoreUI/Atoms/Buttons/MFTextButton.m index ff4c372c..0a72eee7 100644 --- a/MVMCoreUI/Atoms/Buttons/MFTextButton.m +++ b/MVMCoreUI/Atoms/Buttons/MFTextButton.m @@ -128,12 +128,12 @@ #pragma mark - MVMCoreUIMoleculeViewProtocol -- (void)setWithJSON:(NSDictionary *)json delegate:(NSObject *)delegate additionalData:(NSDictionary *)additionalData { +- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { NSString *color = [json string:KeyTextColor]; if (color) { [self setTitleColor:[UIColor mfGetColorForHex:color] forState:UIControlStateNormal]; } - [self setWithActionMap:json actionDelegate:([delegate conformsToProtocol:@protocol(MVMCoreActionDelegateProtocol)] ? (NSObject *)delegate : nil) additionalData:additionalData buttonDelegate:([delegate conformsToProtocol:@protocol(ButtonDelegateProtocol)] ? (id )delegate : nil)]; + [self setWithActionMap:json delegateObject:delegateObject additionalData:additionalData]; if ([self titleForState:UIControlStateNormal].length == 0) { self.heightConstraint.constant = 0; } else { diff --git a/MVMCoreUI/Atoms/Buttons/PrimaryButton.m b/MVMCoreUI/Atoms/Buttons/PrimaryButton.m index fd7ad2b9..2085b5c8 100644 --- a/MVMCoreUI/Atoms/Buttons/PrimaryButton.m +++ b/MVMCoreUI/Atoms/Buttons/PrimaryButton.m @@ -648,10 +648,11 @@ [self setAsStandardCustom]; } -- (void)setWithJSON:(NSDictionary *)json delegate:(NSObject *)delegate additionalData:(nullable NSDictionary *)additionalData { - - [FormValidator setupValidationWithMolecule:self delegate:(id)delegate]; - +- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { + if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { + [FormValidator setupValidationWithMolecule:self delegate:((MVMCoreUIDelegateObject *)delegateObject).formValidationProtocol]; + } + self.primaryButtonType = PrimaryButtonTypeCustom; NSString *color = [json string:@"fillColor"]; if (color) { @@ -676,7 +677,7 @@ self.validationRequired = [json boolForKey:@"validationRequired"]; [self setAsSmallButton:[json boolForKey:@"small"]]; - [self setWithActionMap:json actionDelegate:([delegate conformsToProtocol:@protocol(MVMCoreActionDelegateProtocol)] ? (NSObject *)delegate : nil) additionalData:additionalData buttonDelegate:([delegate conformsToProtocol:@protocol(ButtonDelegateProtocol)] ? (id )delegate : nil)]; + [self setWithActionMap:json delegateObject:delegateObject additionalData:additionalData]; } #pragma mark - Handling Validations diff --git a/MVMCoreUI/Atoms/Views/MFLabel.h b/MVMCoreUI/Atoms/Views/MFLabel.h index 22308465..7dc4fd8d 100644 --- a/MVMCoreUI/Atoms/Views/MFLabel.h +++ b/MVMCoreUI/Atoms/Views/MFLabel.h @@ -9,6 +9,7 @@ #import #import @class MFSizeObject; +@class DelegateObject; @interface MFLabel : UILabel @@ -49,7 +50,7 @@ // Setters + (void)setLabel:(nullable UILabel *)label withHTML:(nullable NSString *)html; -+ (void)setUILabel:(nullable UILabel *)label withJSON:(nullable NSDictionary *)json delegate:(nullable NSObject *)delegate additionalData:(nullable NSDictionary *)additionalData; ++ (void)setUILabel:(nullable UILabel *)label withJSON:(nullable NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData; - (void)styleH1:(BOOL)scale; - (void)styleH2:(BOOL)scale; diff --git a/MVMCoreUI/BaseControllers/MFViewController.m b/MVMCoreUI/BaseControllers/MFViewController.m index 6b27c7d9..c378391a 100644 --- a/MVMCoreUI/BaseControllers/MFViewController.m +++ b/MVMCoreUI/BaseControllers/MFViewController.m @@ -138,7 +138,7 @@ // Creates an initial load object if needed. if (!self.loadObject) { - self.loadObject = [[MVMCoreLoadObject alloc] initWithDelegate:self]; + self.loadObject = [[MVMCoreLoadObject alloc] initWithDelegateObject:[self delegateObject]]; } // Avoid the setter so we are only setting the bool and wait for view will appear to update the navigation bar. @@ -343,7 +343,7 @@ if (rightPanelLinkDict) { [[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:rightPanelLinkDict additionalData:nil - delegate:self]; + delegateObject:[self delegateObject]]; return YES; } else { return NO; @@ -607,7 +607,7 @@ [self.formValidator addFormParamsWithRequestParameters:requestParameters]; requestParameters.parentPageType = [self.loadObject.pageJSON stringForKey:@"parentPageType"]; - [[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParameters dataForPage:additionalData delegate:self]; + [[MVMCoreLoadHandler sharedGlobal] loadRequest:requestParameters dataForPage:additionalData delegateObject:[self delegateObject]]; } - (void)handleBackAction:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData { @@ -662,7 +662,7 @@ - (void)handleUnknownActionType:(nullable NSString *)actionType actionInformation:(nullable NSDictionary *)actionInformation additionalData:(nullable NSDictionary *)additionalData { - [MVMCoreActionHandler defaultHandleUnknownActionType:actionType actionInformation:actionInformation additionalData:additionalData delegate:self]; + [MVMCoreActionHandler defaultHandleUnknownActionType:actionType actionInformation:actionInformation additionalData:additionalData delegateObject:[self delegateObject]]; } - (void)handleActionError:(nonnull MVMCoreErrorObject *)error additionalData:(nullable NSDictionary *)additionalData { @@ -689,7 +689,7 @@ } - (nullable MVMCoreAlertObject *)alertObjectToShow:(nonnull MVMCoreLoadObject *)loadObject error:(nullable MVMCoreErrorObject *)errorObject { - return [MVMCoreAlertObject alertObjectForLoadObject:loadObject error:errorObject actionDelegate:self]; + return [MVMCoreAlertObject alertObjectForLoadObject:loadObject error:errorObject delegateObject:[self delegateObject]]; } - (void)handleFieldErrors:(nullable NSArray *)fieldErrors loadObject:(nonnull MVMCoreLoadObject *)loadObject { diff --git a/MVMCoreUI/Containers/TabBarController/MVMCoreUITabBarPageControlViewController.m b/MVMCoreUI/Containers/TabBarController/MVMCoreUITabBarPageControlViewController.m index 489a4696..d06ca5f4 100644 --- a/MVMCoreUI/Containers/TabBarController/MVMCoreUITabBarPageControlViewController.m +++ b/MVMCoreUI/Containers/TabBarController/MVMCoreUITabBarPageControlViewController.m @@ -394,7 +394,7 @@ if (customAdditionalData) { [additionalData addEntriesFromDictionary:customAdditionalData]; } - [[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:actionMap additionalData:additionalData delegate:self]; + [[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:actionMap additionalData:additionalData delegateObject:[self delegateObject]]; } } return NO; diff --git a/MVMCoreUI/FormUIHelpers/FormValidator+FormParams.swift b/MVMCoreUI/FormUIHelpers/FormValidator+FormParams.swift index 2f1e9f99..17da0e72 100644 --- a/MVMCoreUI/FormUIHelpers/FormValidator+FormParams.swift +++ b/MVMCoreUI/FormUIHelpers/FormValidator+FormParams.swift @@ -9,11 +9,11 @@ import Foundation @objc public extension FormValidator { - @objc public func addFormParams(requestParameters: MVMCoreRequestParameters) { + @objc func addFormParams(requestParameters: MVMCoreRequestParameters) { requestParameters.add(self.getFormParams()) } - @objc public func getFormParams() -> [String: Any] { + @objc func getFormParams() -> [String: Any] { var extraParam: [String: Any] = [:] MVMCoreDispatchUtility.performSyncBlock(onMainThread: { for molecule in self.molecules { diff --git a/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsTableViewController.m b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsTableViewController.m index 7a16405b..ca75b778 100644 --- a/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsTableViewController.m +++ b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsTableViewController.m @@ -117,7 +117,7 @@ // Sets up the buttons/button. NSDictionary *primaryButtonDictionary = [self primaryButtonMap]; NSDictionary *secondaryButtonDictionary = [self secondaryButtonMap]; - TwoButtonView *buttonView = [[TwoButtonView alloc] initWithPrimaryButtonMap:primaryButtonDictionary secondaryButtonMap:secondaryButtonDictionary actionDelegate:self additionalData:nil buttonDelegate:self]; + TwoButtonView *buttonView = [[TwoButtonView alloc] initWithPrimaryButtonMap:primaryButtonDictionary secondaryButtonMap:secondaryButtonDictionary delegateObject:[self delegateObject] additionalData:nil]; self.secondaryButton = buttonView.secondaryButton; self.primaryButton = buttonView.primaryButton; diff --git a/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.m b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.m index be14e149..149b399c 100644 --- a/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.m +++ b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.m @@ -127,7 +127,7 @@ // Sets up the buttons/button. NSDictionary *primaryButtonDictionary = [self primaryButtonMap]; NSDictionary *secondaryButtonDictionary = [self secondaryButtonMap]; - TwoButtonView *buttonView = [[TwoButtonView alloc] initWithPrimaryButtonMap:primaryButtonDictionary secondaryButtonMap:secondaryButtonDictionary actionDelegate:self additionalData:nil buttonDelegate:self]; + TwoButtonView *buttonView = [[TwoButtonView alloc] initWithPrimaryButtonMap:primaryButtonDictionary secondaryButtonMap:secondaryButtonDictionary delegateObject:[self delegateObject] additionalData:nil]; self.secondaryButton = buttonView.secondaryButton; self.primaryButton = buttonView.primaryButton; bottomView = buttonView; diff --git a/MVMCoreUI/Molecules/TwoButtonView.swift b/MVMCoreUI/Molecules/TwoButtonView.swift index 58586126..66b7210a 100644 --- a/MVMCoreUI/Molecules/TwoButtonView.swift +++ b/MVMCoreUI/Molecules/TwoButtonView.swift @@ -150,6 +150,17 @@ import UIKit } // MARK: - Legacy + public convenience init(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { + self.init() + setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) + } + + public convenience init(buttonSmall small: Bool, buttonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: AnyHashable]?) { + self.init() + setup(withButtonMap: buttonMap, delegateObject: delegateObject, additionalData: additionalData) + primaryButton?.setAsSmall(small) + secondaryButton?.setAsSmall(small) + } public convenience init(buttonSmall small: Bool, enabled: Bool) { self.init() @@ -159,6 +170,26 @@ import UIKit primaryButton?.isEnabled = enabled } + open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { + setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, legacy: true) + if primaryButtonMap != nil, secondaryButtonMap != nil { + primaryButton?.setWithActionMap(primaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) + secondaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) + } else if primaryButtonMap != nil { + primaryButton?.setWithActionMap(primaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) + primaryButton?.bordered = false + } else if secondaryButtonMap != nil { + primaryButton?.setWithActionMap(secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) + primaryButton?.bordered = true + } + } + + open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) { + let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton) + let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton) + setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData) + } + public func hidePrimaryLeftButton() { guard let secondaryButton = secondaryButton, !secondaryButton.isHidden else { return From 01c5abc0272c776323003fc0825da8a8d5468e51 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 15 Apr 2019 13:47:19 -0400 Subject: [PATCH 25/27] warning fix --- MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.m | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.m b/MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.m index 4b19c49c..fe8d940b 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.m +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertBaseView.m @@ -19,6 +19,8 @@ #import "MVMCoreUICommonViewsUtility.h" #import "MFStyler.h" #import "MVMCoreUISession.h" +#import + @import MVMCore.MVMCoreTopAlertDelegateProtocol; @implementation MVMCoreUITopAlertBaseView @@ -35,7 +37,7 @@ } if (performAction) { - [[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:actionMap additionalData:additionalData delegate:[MVMCoreUISession sharedGlobal].topAlertView]; + [[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:actionMap additionalData:additionalData delegateObject:[MVMCoreUIDelegateObject createWithDelegateForAll:[MVMCoreUISession sharedGlobal].topAlertView]]; } } forControlEvents:UIControlEventTouchUpInside]; } From e2e6cbabf6f16e74db34f4f01f2440bf2632dbf7 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 15 Apr 2019 14:39:37 -0400 Subject: [PATCH 26/27] textfield delegate object fix --- MVMCoreUI/Atoms/TextFields/MFTextField.m | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/MVMCoreUI/Atoms/TextFields/MFTextField.m b/MVMCoreUI/Atoms/TextFields/MFTextField.m index 565e086c..77509325 100644 --- a/MVMCoreUI/Atoms/TextFields/MFTextField.m +++ b/MVMCoreUI/Atoms/TextFields/MFTextField.m @@ -116,7 +116,7 @@ + (nullable instancetype)mfTextFieldWithMap:(nullable NSDictionary *)map bothDelegates:(nullable id)delegate { MFTextField *textField = [self mfTextField]; textField.translatesAutoresizingMaskIntoConstraints = NO; - [textField setWithJSON:map delegate:delegate additionalData:nil]; + [textField setWithJSON:map delegateObject:[MVMCoreUIDelegateObject createWithDelegateForAll:delegate] additionalData:nil]; return textField; } @@ -558,10 +558,12 @@ self.isMolecule = YES; } -- (void)setWithJSON:(NSDictionary *)json delegate:(nullable id)delegate additionalData:(NSDictionary *)additionalData { - [FormValidator setupValidationWithMolecule:self delegate:(id)delegate]; - FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:(id)delegate]; - [self setWithMap:json bothDelegates:formValidator]; +- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { + if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) { + [FormValidator setupValidationWithMolecule:self delegate:((MVMCoreUIDelegateObject *)delegateObject).formValidationProtocol]; + FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:((MVMCoreUIDelegateObject *)delegateObject).formValidationProtocol]; + [self setWithMap:json bothDelegates:formValidator]; + } } #pragma mark - FormValidationProtocol From 7343f24e9bb4c5f1148b3eb6e06f72079878be24 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Mon, 15 Apr 2019 15:09:25 -0400 Subject: [PATCH 27/27] missed super --- MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift b/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift index 91ce13c3..eaf892fb 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift @@ -13,6 +13,7 @@ open class MVMCoreUIDelegateObject: DelegateObject { public weak var buttonDelegate: ButtonDelegateProtocol? open override func setAll(withDelegate delegate: Any) { + super.setAll(withDelegate: delegate) formValidationProtocol = delegate as? FormValidationProtocol buttonDelegate = delegate as? ButtonDelegateProtocol }