Merge branch 'develop' into feature/form_checkbox
This commit is contained in:
commit
725a0a914f
@ -157,11 +157,11 @@
|
||||
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 */; };
|
||||
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 */; };
|
||||
DBC4392122491730001AB423 /* LabelWithInternalButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@ -318,11 +318,11 @@
|
||||
D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerViewController.swift; sourceTree = "<group>"; };
|
||||
D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewControllerMappingObject.h; sourceTree = "<group>"; };
|
||||
D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIViewControllerMappingObject.m; sourceTree = "<group>"; };
|
||||
D2C5001B21F8EE66001DA659 /* LabelWithInternalButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LabelWithInternalButton.h; sourceTree = "<group>"; };
|
||||
D2C5001C21F8EE66001DA659 /* LabelWithInternalButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LabelWithInternalButton.m; sourceTree = "<group>"; };
|
||||
D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUIDelegateObject.swift; sourceTree = "<group>"; };
|
||||
DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = "<group>"; };
|
||||
DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = "<group>"; };
|
||||
DBC4391A224421A0001AB423 /* CaretButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretButton.swift; sourceTree = "<group>"; };
|
||||
DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelWithInternalButton.swift; sourceTree = "<group>"; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
@ -568,8 +568,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 */,
|
||||
@ -591,6 +589,7 @@
|
||||
D22D1F19220341F50077CEC0 /* MVMCoreUICheckBox.m */,
|
||||
D22D1F44220496A30077CEC0 /* MVMCoreUISwitch.h */,
|
||||
D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */,
|
||||
DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */,
|
||||
0198F7A02256A80A0066C936 /* MFRadioButton.h */,
|
||||
0198F7A22256A80A0066C936 /* MFRadioButton.m */,
|
||||
);
|
||||
@ -637,6 +636,7 @@
|
||||
D29DF27021E79B2C003B2FB9 /* OtherHandlers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */,
|
||||
D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */,
|
||||
D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */,
|
||||
D29DF27721E7A533003B2FB9 /* MVMCoreUISession.h */,
|
||||
@ -753,7 +753,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 */,
|
||||
01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */,
|
||||
@ -869,11 +868,13 @@
|
||||
D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */,
|
||||
DBC4391922442197001AB423 /* DashLine.swift in Sources */,
|
||||
D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */,
|
||||
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */,
|
||||
D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */,
|
||||
D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */,
|
||||
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 */,
|
||||
@ -929,7 +930,6 @@
|
||||
DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */,
|
||||
0198F7A82256A80B0066C936 /* MFRadioButton.m in Sources */,
|
||||
D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */,
|
||||
D2C5001E21F8EE67001DA659 /* LabelWithInternalButton.m in Sources */,
|
||||
D29DF29C21E7ADB9003B2FB9 /* MFProgrammaticTableViewController.m in Sources */,
|
||||
0105618E224BBE7700E1557D /* FormValidator+TextFields.swift in Sources */,
|
||||
D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */,
|
||||
|
||||
@ -106,15 +106,15 @@ 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]?) {
|
||||
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 }
|
||||
|
||||
|
||||
@ -11,14 +11,14 @@
|
||||
#import <MVMCoreUI/ButtonDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MFButtonProtocol.h>
|
||||
#import <MVMCoreUI/MVMCoreUIMoleculeViewProtocol.h>
|
||||
@import MVMCore.MVMCoreViewProtocol;
|
||||
@class DelegateObject;
|
||||
|
||||
typedef void (^ButtonTapBlock)(id _Nonnull sender);
|
||||
|
||||
extern CGFloat const CloseButtonHeight;
|
||||
extern CGFloat const CloseButtonWidth;
|
||||
|
||||
@interface MFCustomButton : UIButton <MFButtonProtocol, MVMCoreUIMoleculeViewProtocol>
|
||||
@interface MFCustomButton : UIButton <MFButtonProtocol>
|
||||
|
||||
@property (nullable, nonatomic, strong) NSDictionary *actionMap;
|
||||
@property (nullable, nonatomic, weak) id <ButtonDelegateProtocol> 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 <MVMCoreActionDelegateProtocol>*)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 <MVMCoreActionDelegateProtocol>*)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id <ButtonDelegateProtocol>)buttonDelegate;
|
||||
- (void)setWithActionMap:(nullable NSDictionary *)actionMap delegateObject:(nullable DelegateObject *)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 <MVMCoreActionDelegateProtocol>*)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 <MVMCoreActionDelegateProtocol>*)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id <ButtonDelegateProtocol>)buttonDelegate __deprecated;
|
||||
|
||||
@end
|
||||
|
||||
@ -13,6 +13,7 @@
|
||||
@import MVMCore.NSDictionary_MFConvenience;
|
||||
#import "MVMCoreUIUtility.h"
|
||||
#import "MVMCoreUIConstants.h"
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
|
||||
CGFloat const CloseButtonHeight = 40.0f;
|
||||
CGFloat const CloseButtonWidth = 40.0f;
|
||||
@ -37,6 +38,54 @@ CGFloat const CloseButtonWidth = 40.0f;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setWithActionMap:(nullable NSDictionary *)actionMap delegateObject:(nullable DelegateObject *)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]];
|
||||
|
||||
if ([delegateObject isKindOfClass:[MVMCoreUIDelegateObject class]]) {
|
||||
self.buttonDelegate = ((MVMCoreUIDelegateObject *)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 <MVMCoreActionDelegateProtocol>*)delegate additionalData:(nullable NSDictionary *)additionalData {
|
||||
|
||||
self.actionMap = actionMap;
|
||||
@ -53,11 +102,11 @@ CGFloat const CloseButtonWidth = 40.0f;
|
||||
}
|
||||
|
||||
- (void)setWithActionMap:(nullable NSDictionary *)actionMap actionDelegate:(nullable NSObject <MVMCoreActionDelegateProtocol>*)actionDelegate additionalData:(nullable NSDictionary *)additionalData buttonDelegate:(nullable id <ButtonDelegateProtocol>)buttonDelegate {
|
||||
|
||||
|
||||
if (!buttonDelegate) {
|
||||
[self setWithActionMap:actionMap delegate:actionDelegate additionalData:additionalData];
|
||||
} else {
|
||||
|
||||
|
||||
self.actionMap = actionMap;
|
||||
self.titleLabel.numberOfLines = 0;
|
||||
self.titleLabel.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
@ -86,24 +135,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
|
||||
|
||||
@ -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 <MVMCoreActionDelegateProtocol>*)delegate : nil) additionalData:additionalData buttonDelegate:([delegate conformsToProtocol:@protocol(ButtonDelegateProtocol)] ? (id <ButtonDelegateProtocol>)delegate : nil)];
|
||||
[self setWithActionMap:json delegateObject:delegateObject additionalData:additionalData];
|
||||
if ([self titleForState:UIControlStateNormal].length == 0) {
|
||||
self.heightConstraint.constant = 0;
|
||||
} else {
|
||||
|
||||
@ -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
|
||||
|
||||
|
||||
@ -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];
|
||||
}
|
||||
@ -644,10 +648,11 @@
|
||||
[self setAsStandardCustom];
|
||||
}
|
||||
|
||||
- (void)setWithJSON:(NSDictionary *)json delegate:(NSObject *)delegate additionalData:(nullable NSDictionary *)additionalData {
|
||||
|
||||
[FormValidator setupValidationWithMolecule:self delegate:(id<FormValidationProtocol>)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) {
|
||||
@ -672,7 +677,7 @@
|
||||
self.validationRequired = [json boolForKey:@"validationRequired"];
|
||||
|
||||
[self setAsSmallButton:[json boolForKey:@"small"]];
|
||||
[self setWithActionMap:json actionDelegate:([delegate conformsToProtocol:@protocol(MVMCoreActionDelegateProtocol)] ? (NSObject <MVMCoreActionDelegateProtocol>*)delegate : nil) additionalData:additionalData buttonDelegate:([delegate conformsToProtocol:@protocol(ButtonDelegateProtocol)] ? (id <ButtonDelegateProtocol>)delegate : nil)];
|
||||
[self setWithActionMap:json delegateObject:delegateObject additionalData:additionalData];
|
||||
}
|
||||
|
||||
#pragma mark - Handling Validations
|
||||
|
||||
@ -116,7 +116,7 @@
|
||||
+ (nullable instancetype)mfTextFieldWithMap:(nullable NSDictionary *)map bothDelegates:(nullable id<UITextFieldDelegate, MFTextFieldDelegate>)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<UITextFieldDelegate, MFTextFieldDelegate>)delegate additionalData:(NSDictionary *)additionalData {
|
||||
[FormValidator setupValidationWithMolecule:self delegate:(id<FormValidationProtocol>)delegate];
|
||||
FormValidator *formValidator = [FormValidator getFormValidatorForDelegate:(id<FormValidationProtocol>)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
|
||||
|
||||
@ -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 }
|
||||
|
||||
|
||||
@ -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 }
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -1,94 +0,0 @@
|
||||
//
|
||||
// TextMixedWithButtonView.h
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Chris Yang on 2/25/16.
|
||||
// Copyright © 2016 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import<UIKit/UIKit.h>
|
||||
#import <MVMCore/MVMCoreActionDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MFView.h>
|
||||
#import <MVMCoreUI/MFLabel.h>
|
||||
#import <MVMCoreUI/ButtonDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MFButtonProtocol.h>
|
||||
|
||||
typedef void (^ActionBlock)(void);
|
||||
|
||||
@interface LabelWithInternalButton : UIControl <MVMCoreViewProtocol, MFButtonProtocol>
|
||||
|
||||
@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<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)buttonDelegate;
|
||||
- (nullable instancetype)initWithFrontText:(nullable NSString *)frontText backText:(nullable NSString *)backText actionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)buttonDelegate;
|
||||
// set with button delegate
|
||||
- (void)setActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)buttonDelegate;
|
||||
- (void)setFrontText:(nullable NSString *)frontText actionMap:(nullable NSDictionary *)actionMap backText:(nullable NSString *)backText additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)buttonDelegate;
|
||||
- (void)setFrontAttributedText:(nullable NSAttributedString *)frontAttributedText actionMap:(nullable NSDictionary *)actionMap backAttributedText:(nullable NSAttributedString *)backText additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)buttonDelegate;
|
||||
- (void)setFrontAttributedText:(nullable NSAttributedString *)frontAttributedText actionMap:(nullable NSDictionary *)actionMap backAttributedText:(nullable NSAttributedString *)backAttributedText addNewLine:(BOOL) addNewLine additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)delegate;
|
||||
|
||||
- (nullable instancetype)initWithActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)delegate;
|
||||
|
||||
|
||||
//set action map
|
||||
- (void)setActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)delegate;
|
||||
- (void)setFrontAttributedText:(nullable NSAttributedString *)frontAttributedText actionMap:(nullable NSDictionary *)actionMap backAttributedText:(nullable NSAttributedString *)backAttributedText addNewLine:(BOOL) addNewLine additionalData:(nullable NSDictionary *)additionalData delegate:(nullable NSObject<MVMCoreActionDelegateProtocol> *)delegate;
|
||||
|
||||
- (void)resetWithActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary * )additionalData delegate:(nullable NSObject<MVMCoreActionDelegateProtocol> *)delegate;
|
||||
|
||||
- (void)setAlignment:(NSTextAlignment)textAlignment;
|
||||
|
||||
- (void)setEnabled:(BOOL)enabled;
|
||||
|
||||
- (void)setAlternateActionTextAttributes:(nullable NSDictionary *)attributes;
|
||||
|
||||
- (void)setActionTextString:(nullable NSString *)actionText;
|
||||
|
||||
- (nonnull UIAccessibilityCustomAction *)accessibilityCustomAction;
|
||||
|
||||
@end
|
||||
@ -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 <MVMCore/UILabel+MFCustom.h>
|
||||
#import <MVMCore/NSDictionary+MFConvenience.h>
|
||||
#import <MVMCoreUI/MFFonts.h>
|
||||
#import <MVMCore/MVMCoreJSONConstants.h>
|
||||
#import <MVMCoreUI/UIColor+MFConvenience.h>
|
||||
#import <MVMCoreUI/MFStyler.h>
|
||||
#import <MVMCoreUI/MVMCoreUIConstants.h>
|
||||
#import <MVMCore/MVMCoreConstants.h>
|
||||
#import <MVMCore/MVMCoreActionHandler.h>
|
||||
|
||||
@interface LabelWithInternalButton ()
|
||||
|
||||
@property (nullable, strong, nonatomic) NSString *text;
|
||||
|
||||
@end
|
||||
|
||||
@implementation LabelWithInternalButton
|
||||
|
||||
|
||||
|
||||
- (nullable instancetype)initWithActionMap:(nullable NSDictionary *)actionMap additionalData:(nullable NSDictionary *)additionalData actionDelegate:(nullable NSObject <MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)delegate buttonDelegate:(nullable NSObject<ButtonDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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 <MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<UITouch *> *)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<UITouch *> *)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 <MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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<MVMCoreActionDelegateProtocol> *)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
|
||||
604
MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift
Normal file
604
MVMCoreUI/Atoms/Views/LabelWithInternalButton.swift
Normal file
@ -0,0 +1,604 @@
|
||||
//
|
||||
// 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
|
||||
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
|
||||
|
||||
|
||||
@objcMembers open class LabelWithInternalButton: UIControl, MVMCoreViewProtocol, MFButtonProtocol {
|
||||
//------------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//------------------------------------------------------
|
||||
|
||||
public var actionBlock: ActionBlock?
|
||||
public weak var label: MFLabel?
|
||||
|
||||
public var attributedText: NSAttributedString? {
|
||||
willSet(newAttributedText) {
|
||||
if let newAttribText = newAttributedText, !newAttribText.string.isEmpty {
|
||||
|
||||
let mutableAttributedText = NSMutableAttributedString(attributedString: newAttribText)
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
paragraphStyle.lineSpacing = CGFloat(LabelWithInternalButtonLineSpace)
|
||||
mutableAttributedText.addAttribute(.paragraphStyle, value: paragraphStyle, range: NSRange(location: 0, length: newAttribText.length))
|
||||
label?.attributedText = mutableAttributedText
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// By default, it will follow most of the font standard in zepplin, and should need to be changed
|
||||
public var normalTextFont: UIFont? = MFStyler.fontB2() {
|
||||
willSet(newNormalFont) {
|
||||
setAlternateNormalTextAttributes([NSAttributedString.Key.font: newNormalFont as Any])
|
||||
}
|
||||
}
|
||||
|
||||
public var actionTextFont: UIFont? = MFStyler.fontB2() {
|
||||
willSet(newActionFont) {
|
||||
setAlternateActionTextAttributes([NSAttributedString.Key.font: newActionFont as Any])
|
||||
}
|
||||
}
|
||||
|
||||
public var normalTextColor: UIColor = .black {
|
||||
willSet(newNormalColor) {
|
||||
setAlternateNormalTextAttributes([NSAttributedString.Key.foregroundColor: newNormalColor as Any])
|
||||
}
|
||||
}
|
||||
|
||||
public var actionTextColor: UIColor = .black {
|
||||
willSet(newActionColor) {
|
||||
setAlternateActionTextAttributes([NSAttributedString.Key.foregroundColor: newActionColor as Any])
|
||||
}
|
||||
}
|
||||
|
||||
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?
|
||||
|
||||
private var text: String? {
|
||||
willSet(newText) {
|
||||
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.isUserInteractionEnabled = false
|
||||
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()
|
||||
}
|
||||
|
||||
// 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) ?? false
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
if let b2Font = MFStyler.fontB2(),
|
||||
let actions = actionMap,
|
||||
actions.keys.count > 0,
|
||||
let actionString = actions.optionalStringForKey(KeyTitle),
|
||||
!actionString.isEmpty {
|
||||
|
||||
let actionStringOnLine = actionString + (addNewLine ? "\n" : " ")
|
||||
actionText = actionStringOnLine
|
||||
setActionMap(actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: buttonDelegate)
|
||||
mutableAttributedString.append(MFStyler.styleGetAttributedString(actionStringOnLine, font: b2Font, color: .black))
|
||||
|
||||
} 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<UITouch>, 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<UITouch>?) -> 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, let backTxt = backText, !backTxt.isEmpty {
|
||||
actionText?.append(" ")
|
||||
}
|
||||
|
||||
return "\(frontText ?? "")\(actionText ?? "")\(backText ?? "")"
|
||||
}
|
||||
|
||||
private func getActionRange() -> NSRange {
|
||||
|
||||
return NSRange(location: frontText?.count ?? 0, length: actionText?.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 actionableTuple: ActionableStringTuple = rangeOfText(text, startTag: startTag, endTag: endTag)
|
||||
|
||||
if let front = actionableTuple.front, let middle = actionableTuple.middle, let end = actionableTuple.end {
|
||||
frontText = front.trimmingCharacters(in: .whitespaces)
|
||||
actionText = middle.trimmingCharacters(in: .whitespaces)
|
||||
backText = end.trimmingCharacters(in: .whitespaces)
|
||||
self.text = getTextFromStringComponents()
|
||||
} else {
|
||||
frontText = text
|
||||
self.text = text
|
||||
}
|
||||
|
||||
setup()
|
||||
}
|
||||
|
||||
private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> ActionableStringTuple {
|
||||
|
||||
var actionableTuple: ActionableStringTuple = (front: nil, middle: nil, end: nil)
|
||||
|
||||
guard let text = text else { return actionableTuple }
|
||||
|
||||
if let leftTag = startTag, text.contains(leftTag) {
|
||||
|
||||
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]
|
||||
}
|
||||
}
|
||||
|
||||
return actionableTuple
|
||||
}
|
||||
|
||||
@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]?) {
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
public func setAlternateNormalTextAttributes(_ attributes: [AnyHashable: Any]?) {
|
||||
|
||||
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 {
|
||||
|
||||
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
|
||||
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 {
|
||||
return UIAccessibilityCustomAction(name: actionTxt, target: self, selector: #selector(LabelWithInternalButton.accessibilityCustomActions))
|
||||
}
|
||||
|
||||
return UIAccessibilityCustomAction()
|
||||
}
|
||||
}
|
||||
|
||||
extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol {
|
||||
//------------------------------------------------------
|
||||
// MARK: - Atomization
|
||||
//------------------------------------------------------
|
||||
|
||||
// Default values for view.
|
||||
@objc open func setAsMolecule() {
|
||||
|
||||
}
|
||||
|
||||
@objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
// Configure class properties with JSON values
|
||||
guard let dictionary = json else { return }
|
||||
|
||||
if let backgroundColorHex = dictionary[KeyBackgroundColor] as? String {
|
||||
self.backgroundColor = UIColor.mfGet(forHex: backgroundColorHex)
|
||||
}
|
||||
|
||||
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 willSet feature.
|
||||
if let text = dictionary["text"] as? String {
|
||||
self.text = text
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -9,6 +9,7 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MVMCoreUI/MFView.h>
|
||||
@class MFSizeObject;
|
||||
@class DelegateObject;
|
||||
|
||||
@interface MFLabel : UILabel <MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol>
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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:(DelegateObject *)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:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
|
||||
[MFLabel setUILabel:self withJSON:json delegateObject:delegateObject additionalData:additionalData];
|
||||
self.originalAttributedString = self.attributedText;
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
|
||||
@ -7,6 +7,7 @@
|
||||
//
|
||||
|
||||
#import "MFView.h"
|
||||
@import MVMCore.Swift;
|
||||
|
||||
@implementation MFView
|
||||
|
||||
@ -43,7 +44,7 @@
|
||||
|
||||
#pragma mark - MVMCoreUIMoleculeViewProtocol
|
||||
|
||||
- (void)setWithJSON:(NSDictionary *)json delegate:(NSObject *)delegate additionalData:(nullable NSDictionary *)additionalData {
|
||||
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
|
||||
self.json = json;
|
||||
}
|
||||
|
||||
|
||||
@ -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];
|
||||
|
||||
@ -140,7 +140,6 @@
|
||||
#pragma mark - MVMCoreUIMoleculeViewProtocol
|
||||
|
||||
- (void)setAsMolecule {
|
||||
self.updateViewHorizontalDefaults = YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
@class MainMenuViewController;
|
||||
@class MVMCoreUITabBarPageControlViewController;
|
||||
@class MVMAnimationManager;
|
||||
@class DelegateObject;
|
||||
|
||||
@interface MFViewController : UIViewController <MVMCoreLoadDelegateProtocol, MVMCorePresentationDelegateProtocol, MVMCoreActionDelegateProtocol, UITextFieldDelegate, UITextViewDelegate, MFTextFieldDelegate, ButtonDelegateProtocol, MVMCoreViewControllerProtocol, MVMCoreViewManagerViewControllerProtocol, MVMCoreUIDetailViewProtocol>
|
||||
|
||||
|
||||
@ -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.
|
||||
@ -180,6 +180,10 @@
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (nullable DelegateObject *)delegateObject {
|
||||
return [MVMCoreUIDelegateObject createWithDelegateForAll:self];
|
||||
}
|
||||
|
||||
#pragma mark - Response Handling
|
||||
|
||||
- (void)observeForResponseJSONUpdates {
|
||||
@ -339,7 +343,7 @@
|
||||
if (rightPanelLinkDict) {
|
||||
[[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:rightPanelLinkDict
|
||||
additionalData:nil
|
||||
delegate:self];
|
||||
delegateObject:[self delegateObject]];
|
||||
return YES;
|
||||
} else {
|
||||
return NO;
|
||||
@ -603,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 {
|
||||
@ -658,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 {
|
||||
@ -685,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 {
|
||||
|
||||
@ -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 <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
|
||||
+ (void)populateView:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray useMargins:(BOOL)useMargins withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
|
||||
+ (void)populateViewHorizontally:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
|
||||
+ (void)populateView:(nonnull UIView *)view withUIArrayForConstrainingViews:(nonnull NSArray <UIView *>*)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 <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
|
||||
+ (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray useMargins:(BOOL)useMargins withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
|
||||
+ (void)autoLayoutViewHorizontally:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
|
||||
+ (void)autoLayoutViewWithConstrainingViewsWithUIArray:(nonnull NSArray <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock;
|
||||
|
||||
|
||||
@ -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 <UIView *>*)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 <UIView *>*)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 <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock {
|
||||
+ (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray <UIView *>*)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 <UIView *>*)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 <UIView *>*)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock {
|
||||
if ([formUIArray count] > 0) {
|
||||
|
||||
|
||||
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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).
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -74,7 +74,6 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[];
|
||||
#pragma mark Views
|
||||
#import <MVMCoreUI/MFView.h>
|
||||
#import <MVMCoreUI/MFLabel.h>
|
||||
#import <MVMCoreUI/LabelWithInternalButton.h>
|
||||
#import <MVMCoreUI/ViewConstrainingView.h>
|
||||
#import <MVMCoreUI/MFLoadingSpinner.h>
|
||||
#import <MVMCoreUI/MFTextView.h>
|
||||
|
||||
@ -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,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: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
primaryButton?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
// MARK: - Constraining
|
||||
|
||||
@ -7,11 +7,12 @@
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
@class DelegateObject;
|
||||
|
||||
@protocol MVMCoreUIMoleculeViewProtocol <NSObject>
|
||||
|
||||
// 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 DelegateObject *)delegateObject additionalData:(nullable NSDictionary *)additionalData;
|
||||
|
||||
@optional
|
||||
|
||||
|
||||
@ -11,18 +11,19 @@ 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)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
@ -47,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
|
||||
}
|
||||
@ -57,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)
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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)
|
||||
@ -34,18 +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")
|
||||
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, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
// MARK: - Constraining
|
||||
@ -141,25 +142,24 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
// 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 set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON, legacy: false)
|
||||
setDefaultCustom()
|
||||
primaryButton?.setWithJSON(primaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData)
|
||||
secondaryButton?.setWithJSON(secondaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
// 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) {
|
||||
@ -170,16 +170,24 @@ 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: buttonMap)
|
||||
primaryButton?.setAsSmall(small)
|
||||
secondaryButton?.setAsSmall(small)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
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() {
|
||||
@ -221,3 +229,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)
|
||||
}
|
||||
}
|
||||
|
||||
20
MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift
Normal file
20
MVMCoreUI/OtherHandlers/MVMCoreUIDelegateObject.swift
Normal file
@ -0,0 +1,20 @@
|
||||
//
|
||||
// DelegateObject.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/12/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
open class MVMCoreUIDelegateObject: DelegateObject {
|
||||
public weak var formValidationProtocol: FormValidationProtocol?
|
||||
public weak var buttonDelegate: ButtonDelegateProtocol?
|
||||
|
||||
open override func setAll(withDelegate delegate: Any) {
|
||||
super.setAll(withDelegate: delegate)
|
||||
formValidationProtocol = delegate as? FormValidationProtocol
|
||||
buttonDelegate = delegate as? ButtonDelegateProtocol
|
||||
}
|
||||
}
|
||||
@ -7,7 +7,6 @@
|
||||
//
|
||||
|
||||
@import MVMCore.MVMCoreLoggingHandler;
|
||||
@class MVMCoreTopAlertObject;
|
||||
@class MFViewController;
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MVMCoreUI/MVMCoreUIMoleculeViewProtocol.h>
|
||||
@class DelegateObject;
|
||||
|
||||
@interface MVMCoreUIMoleculeMappingObject : NSObject
|
||||
|
||||
@ -19,6 +20,6 @@
|
||||
|
||||
// Returns the molecule for the given name.
|
||||
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForName:(nonnull NSString *)name;
|
||||
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForJSON:(nonnull NSDictionary *)json delegate:(nullable NSObject *)delegate;
|
||||
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject;
|
||||
|
||||
@end
|
||||
|
||||
@ -56,13 +56,13 @@
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForJSON:(nonnull NSDictionary *)json delegate:(nullable NSObject *)delegate {
|
||||
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable MVMCoreUIDelegateObject *)delegateObject {
|
||||
NSString *moleculeName = [json string:@"moleculeName"];
|
||||
if (!moleculeName) {
|
||||
return nil;
|
||||
}
|
||||
UIView <MVMCoreUIMoleculeViewProtocol>*molecule = [self getMoleculeForName:moleculeName];
|
||||
[molecule setWithJSON:json delegate:delegate additionalData:nil];
|
||||
[molecule setWithJSON:json delegateObject:delegateObject additionalData:nil];
|
||||
return molecule;
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@class LabelWithInternalButton;
|
||||
@class MFSizeObject;
|
||||
|
||||
//enum for border
|
||||
@ -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
|
||||
|
||||
@ -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 {
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
#import <MVMCore/MVMCoreTopAlertAnimationDelegateProtocol.h>
|
||||
#import <MVMCoreUI/MFView.h>
|
||||
|
||||
@class MVMCoreTopAlertObject;
|
||||
@class MFCustomButton;
|
||||
|
||||
@interface MVMCoreUITopAlertBaseView : MFView
|
||||
|
||||
@ -19,6 +19,8 @@
|
||||
#import "MVMCoreUICommonViewsUtility.h"
|
||||
#import "MFStyler.h"
|
||||
#import "MVMCoreUISession.h"
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
|
||||
@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];
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
#import <MVMCore/MVMCoreTopAlertAnimationDelegateProtocol.h>
|
||||
|
||||
@class PrimaryButton;
|
||||
@class MVMCoreTopAlertObject;
|
||||
|
||||
@interface MVMCoreUITopAlertMainView : MVMCoreUITopAlertBaseView
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user