lc1
This commit is contained in:
commit
7f21ff89bc
@ -96,8 +96,6 @@
|
||||
D29DF28021E7AA51003B2FB9 /* MVMCoreUIDetailViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF27F21E7AA50003B2FB9 /* MVMCoreUIDetailViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF28121E7AB23003B2FB9 /* MVMCoreUICommonViewsUtility.m */; };
|
||||
D29DF28421E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF28221E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D29DF28921E7AC2B003B2FB9 /* MFLabel.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF28521E7AC2B003B2FB9 /* MFLabel.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D29DF28A21E7AC2B003B2FB9 /* MFLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF28621E7AC2B003B2FB9 /* MFLabel.m */; };
|
||||
D29DF28B21E7AC2B003B2FB9 /* ViewConstrainingView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF28721E7AC2B003B2FB9 /* ViewConstrainingView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF28821E7AC2B003B2FB9 /* ViewConstrainingView.m */; };
|
||||
D29DF29521E7ADB8003B2FB9 /* ProgrammaticScrollViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF28D21E7ADB8003B2FB9 /* ProgrammaticScrollViewController.m */; };
|
||||
@ -157,10 +155,15 @@
|
||||
D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; };
|
||||
D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */; };
|
||||
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */; };
|
||||
D2E1FADD2268B25E00AEFD8C /* MoleculeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADC2268B25E00AEFD8C /* MoleculeTableViewCell.swift */; };
|
||||
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */; };
|
||||
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.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 */; };
|
||||
DBEFFA04225A829700230692 /* Label.swift in Sources */ = {isa = PBXBuildFile; fileRef = DB891E822253FA8500022516 /* Label.swift */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
@ -262,8 +265,6 @@
|
||||
D29DF27F21E7AA50003B2FB9 /* MVMCoreUIDetailViewProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIDetailViewProtocol.h; sourceTree = "<group>"; };
|
||||
D29DF28121E7AB23003B2FB9 /* MVMCoreUICommonViewsUtility.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUICommonViewsUtility.m; sourceTree = "<group>"; };
|
||||
D29DF28221E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUICommonViewsUtility.h; sourceTree = "<group>"; };
|
||||
D29DF28521E7AC2B003B2FB9 /* MFLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFLabel.h; sourceTree = "<group>"; };
|
||||
D29DF28621E7AC2B003B2FB9 /* MFLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFLabel.m; sourceTree = "<group>"; };
|
||||
D29DF28721E7AC2B003B2FB9 /* ViewConstrainingView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ViewConstrainingView.h; sourceTree = "<group>"; };
|
||||
D29DF28821E7AC2B003B2FB9 /* ViewConstrainingView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ViewConstrainingView.m; sourceTree = "<group>"; };
|
||||
D29DF28D21E7ADB8003B2FB9 /* ProgrammaticScrollViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ProgrammaticScrollViewController.m; sourceTree = "<group>"; };
|
||||
@ -317,6 +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>"; };
|
||||
D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUIDelegateObject.swift; sourceTree = "<group>"; };
|
||||
DB891E822253FA8500022516 /* Label.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Label.swift; sourceTree = "<group>"; };
|
||||
D2E1FADC2268B25E00AEFD8C /* MoleculeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTableViewController.swift; sourceTree = "<group>"; };
|
||||
D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeListTemplate.swift; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
@ -405,6 +411,7 @@
|
||||
01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */,
|
||||
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */,
|
||||
D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */,
|
||||
D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */,
|
||||
);
|
||||
path = Templates;
|
||||
sourceTree = "<group>";
|
||||
@ -440,6 +447,7 @@
|
||||
D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */,
|
||||
D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */,
|
||||
D274CA322236A78900B01B62 /* StandardFooterView.swift */,
|
||||
D2E1FADC2268B25E00AEFD8C /* MoleculeTableViewCell.swift */,
|
||||
);
|
||||
path = Molecules;
|
||||
sourceTree = "<group>";
|
||||
@ -460,6 +468,7 @@
|
||||
D29DF2CC21E7C104003B2FB9 /* MFLoadingViewController.h */,
|
||||
D29DF2CD21E7C104003B2FB9 /* MFLoadingViewController.m */,
|
||||
D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */,
|
||||
D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */,
|
||||
);
|
||||
path = BaseControllers;
|
||||
sourceTree = "<group>";
|
||||
@ -562,8 +571,6 @@
|
||||
DBC4391722442197001AB423 /* DashLine.swift */,
|
||||
D29DF17E21E69E2E003B2FB9 /* MFView.h */,
|
||||
D29DF17F21E69E2E003B2FB9 /* MFView.m */,
|
||||
D29DF28521E7AC2B003B2FB9 /* MFLabel.h */,
|
||||
D29DF28621E7AC2B003B2FB9 /* MFLabel.m */,
|
||||
D29DF31E21ED0CBA003B2FB9 /* LabelView.h */,
|
||||
D29DF31F21ED0CBA003B2FB9 /* LabelView.m */,
|
||||
D29DF28721E7AC2B003B2FB9 /* ViewConstrainingView.h */,
|
||||
@ -588,6 +595,7 @@
|
||||
D22D1F44220496A30077CEC0 /* MVMCoreUISwitch.h */,
|
||||
D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */,
|
||||
DBC4391C2245232D001AB423 /* LabelWithInternalButton.swift */,
|
||||
DB891E822253FA8500022516 /* Label.swift */,
|
||||
0198F7A02256A80A0066C936 /* MFRadioButton.h */,
|
||||
0198F7A22256A80A0066C936 /* MFRadioButton.m */,
|
||||
);
|
||||
@ -634,6 +642,7 @@
|
||||
D29DF27021E79B2C003B2FB9 /* OtherHandlers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */,
|
||||
D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */,
|
||||
D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */,
|
||||
D29DF27721E7A533003B2FB9 /* MVMCoreUISession.h */,
|
||||
@ -742,7 +751,6 @@
|
||||
D29DF27521E79E81003B2FB9 /* MVMCoreUILoggingHandler.h in Headers */,
|
||||
D29DF28B21E7AC2B003B2FB9 /* ViewConstrainingView.h in Headers */,
|
||||
D29DF2B321E7B76D003B2FB9 /* MFLoadingSpinner.h in Headers */,
|
||||
D29DF28921E7AC2B003B2FB9 /* MFLabel.h in Headers */,
|
||||
D29DF32521ED0DA2003B2FB9 /* TextButtonView.h in Headers */,
|
||||
D29DF25021E6A177003B2FB9 /* MFDigitTextBox.h in Headers */,
|
||||
D29DF2C621E7BF57003B2FB9 /* MFTabBarInteractor.h in Headers */,
|
||||
@ -865,6 +873,7 @@
|
||||
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 */,
|
||||
@ -887,12 +896,14 @@
|
||||
D29DF25421E6A177003B2FB9 /* MFMdnTextField.m in Sources */,
|
||||
D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */,
|
||||
D2A514672213885800345BFB /* StandardHeaderView.swift in Sources */,
|
||||
DBEFFA04225A829700230692 /* Label.swift in Sources */,
|
||||
D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */,
|
||||
D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */,
|
||||
D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */,
|
||||
D29DF2EF21ECEAE1003B2FB9 /* MFFonts.m in Sources */,
|
||||
D282AACB2243C61700C46919 /* ButtonView.swift in Sources */,
|
||||
0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */,
|
||||
D2E1FADD2268B25E00AEFD8C /* MoleculeTableViewCell.swift in Sources */,
|
||||
D29DF2AE21E7B3A4003B2FB9 /* MFTextView.m in Sources */,
|
||||
D29DF18121E69E50003B2FB9 /* MFView.m in Sources */,
|
||||
D29DF18321E69E54003B2FB9 /* SeparatorView.m in Sources */,
|
||||
@ -900,7 +911,6 @@
|
||||
D274CA332236A78900B01B62 /* StandardFooterView.swift in Sources */,
|
||||
D29DF2BF21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.m in Sources */,
|
||||
D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */,
|
||||
D29DF28A21E7AC2B003B2FB9 /* MFLabel.m in Sources */,
|
||||
D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationController.m in Sources */,
|
||||
D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */,
|
||||
01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */,
|
||||
@ -909,6 +919,7 @@
|
||||
D29DF2C721E7BF57003B2FB9 /* MFTabBarInteractor.m in Sources */,
|
||||
D29DF29521E7ADB8003B2FB9 /* ProgrammaticScrollViewController.m in Sources */,
|
||||
D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */,
|
||||
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
|
||||
D22D1F47220496A30077CEC0 /* MVMCoreUISwitch.m in Sources */,
|
||||
D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */,
|
||||
D29DF17B21E69E1F003B2FB9 /* PrimaryButton.m in Sources */,
|
||||
@ -916,6 +927,7 @@
|
||||
0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */,
|
||||
D29DF29821E7ADB8003B2FB9 /* MFScrollingViewController.m in Sources */,
|
||||
D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */,
|
||||
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */,
|
||||
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */,
|
||||
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
|
||||
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */,
|
||||
|
||||
@ -8,13 +8,14 @@
|
||||
//
|
||||
|
||||
|
||||
open class CaretButton: MFCustomButton {
|
||||
open class CaretButton: MFCustomButton, MVMCoreUIMoleculeViewProtocol {
|
||||
//------------------------------------------------------
|
||||
// MARK: - Constants
|
||||
//------------------------------------------------------
|
||||
|
||||
private let CaretViewHeight: Float = 10.8
|
||||
private let CaretViewWidth: Float = 6.6
|
||||
private let CARET_VIEW_HEIGHT: Float = 10.5
|
||||
private let CARET_VIEW_WIDTH: Float = 6.5
|
||||
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Properties
|
||||
@ -25,17 +26,11 @@ open class CaretButton: MFCustomButton {
|
||||
@objc public var rightViewWidth: NSNumber?
|
||||
|
||||
@objc public var enabledColor: UIColor = .black {
|
||||
didSet {
|
||||
setTitleColor(enabledColor, for: .normal)
|
||||
changeCaretColor()
|
||||
}
|
||||
didSet { changeCaretColor() }
|
||||
}
|
||||
|
||||
@objc public var disabledColor: UIColor = .mfSilver() {
|
||||
didSet {
|
||||
setTitleColor(disabledColor, for: .disabled)
|
||||
changeCaretColor()
|
||||
}
|
||||
didSet { changeCaretColor() }
|
||||
}
|
||||
|
||||
private var caretSpacingConstraint: NSLayoutConstraint?
|
||||
@ -61,9 +56,11 @@ open class CaretButton: MFCustomButton {
|
||||
//------------------------------------------------------
|
||||
|
||||
private func changeCaretColor() {
|
||||
|
||||
setTitleColor(enabledColor, for: .normal)
|
||||
setTitleColor(disabledColor, for: .disabled)
|
||||
|
||||
if let rightCaretView = rightView as? CaretView {
|
||||
rightCaretView.tintColor = isEnabled ? enabledColor : disabledColor
|
||||
rightCaretView.setLineColor(isEnabled ? enabledColor : disabledColor)
|
||||
}
|
||||
}
|
||||
|
||||
@ -71,8 +68,8 @@ open class CaretButton: MFCustomButton {
|
||||
|
||||
rightView?.removeFromSuperview()
|
||||
|
||||
let width = CGFloat(rightViewWidth?.floatValue ?? CaretViewWidth)
|
||||
let height = CGFloat(rightViewHeight?.floatValue ?? CaretViewHeight)
|
||||
let width = CGFloat(rightViewWidth?.floatValue ?? CARET_VIEW_WIDTH)
|
||||
let height = CGFloat(rightViewHeight?.floatValue ?? CARET_VIEW_HEIGHT)
|
||||
|
||||
let edgeInsets: UIEdgeInsets = contentEdgeInsets
|
||||
contentEdgeInsets = UIEdgeInsets(top: edgeInsets.top, left: edgeInsets.left, bottom: edgeInsets.bottom, right: 4 + width)
|
||||
@ -106,15 +103,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)
|
||||
@objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
setWithActionMap(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
|
||||
guard let dictionary = json else { return }
|
||||
|
||||
@ -130,4 +127,12 @@ open class CaretButton: MFCustomButton {
|
||||
disabledColor = UIColor.mfGet(forHex: disabledColorHex)
|
||||
}
|
||||
}
|
||||
|
||||
public func needsToBeConstrained() -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
open func moleculeAlignment() -> UIStackView.Alignment {
|
||||
return UIStackView.Alignment.leading;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 {
|
||||
@ -141,4 +141,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)needsToBeConstrained {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (UIStackViewAlignment)moleculeAlignment {
|
||||
return UIStackViewAlignmentLeading;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -648,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) {
|
||||
@ -676,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
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
|
||||
@class PrimaryButton;
|
||||
@class MFTextField;
|
||||
@class MFLabel;
|
||||
@class Label;
|
||||
|
||||
@protocol MFTextFieldDelegate <NSObject>
|
||||
|
||||
@ -34,7 +34,7 @@
|
||||
|
||||
@property (nullable, weak, nonatomic) IBOutlet UIView *textFieldContainerView;
|
||||
@property (nullable, weak, nonatomic) IBOutlet UITextField *textField;
|
||||
@property (nullable, weak, nonatomic) IBOutlet MFLabel *formLabel;
|
||||
@property (nullable, weak, nonatomic) IBOutlet Label *formLabel;
|
||||
@property (nullable, weak, nonatomic) IBOutlet UIView *separatorView;//make it public so outsider class can know the posistion of it.
|
||||
|
||||
@property (nullable, weak, nonatomic) IBOutlet NSLayoutConstraint *heightConstraint;
|
||||
|
||||
@ -7,12 +7,10 @@
|
||||
//
|
||||
|
||||
#import "MFTextField.h"
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
#import "MFTextFieldSubclassExtension.h"
|
||||
#import "MFStyler.h"
|
||||
#import "UIColor+MFConvenience.h"
|
||||
#import "MVMCoreUICommonViewsUtility.h"
|
||||
#import "MFLabel.h"
|
||||
#import "MVMCoreUIUtility.h"
|
||||
#import "MVMCoreUIConstants.h"
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
@ -116,7 +114,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 setWithMap:map bothDelegates:delegate];
|
||||
return textField;
|
||||
}
|
||||
|
||||
@ -326,7 +324,7 @@
|
||||
}
|
||||
|
||||
// key used to send text value to server
|
||||
string = [map string:@"fieldKey"];
|
||||
string = [map string:KeyFieldKey];
|
||||
if (string.length > 0) {
|
||||
self.fieldKey = string;
|
||||
}
|
||||
@ -558,10 +556,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
|
||||
|
||||
@ -1,11 +1,11 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14460.31" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="14490.70" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
|
||||
<device id="retina4_7" orientation="portrait">
|
||||
<adaptation id="fullscreen"/>
|
||||
</device>
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14460.20"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
|
||||
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
@ -98,7 +98,7 @@
|
||||
<nil key="textColor"/>
|
||||
<nil key="highlightedColor"/>
|
||||
</label>
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8zH-YN-qag" customClass="MFLabel">
|
||||
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8zH-YN-qag" customClass="Label" customModule="MVMCoreUI" customModuleProvider="target">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="36"/>
|
||||
<fontDescription key="fontDescription" type="system" pointSize="17"/>
|
||||
<nil key="textColor"/>
|
||||
|
||||
@ -13,15 +13,21 @@ open class CaretView: MFView {
|
||||
// MARK: - Properties
|
||||
//------------------------------------------------------
|
||||
|
||||
// Objc can't use float enum.
|
||||
@objc public static let thin: CGFloat = 6.0
|
||||
@objc public static let standard: CGFloat = 2.6
|
||||
@objc public static let thick: CGFloat = 1.5
|
||||
|
||||
private(set) var strokeColor: UIColor?
|
||||
private var lineWidth: CGFloat?
|
||||
|
||||
private var lineThickness: CGFloat?
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Initialization
|
||||
//------------------------------------------------------
|
||||
|
||||
@objc public init() {
|
||||
super.init(frame: CGRect.zero)
|
||||
super.init(frame: .zero)
|
||||
}
|
||||
|
||||
@objc public override init(frame: CGRect) {
|
||||
@ -32,14 +38,19 @@ open class CaretView: MFView {
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
/// Can init with a specific line width.
|
||||
@objc public init(lineWidth: CGFloat) {
|
||||
super.init(frame: CGRect())
|
||||
|
||||
self.lineWidth = lineWidth
|
||||
}
|
||||
|
||||
/// Can init with a specific line thickness, scales based on width and height.
|
||||
@objc public init(lineThickness: CGFloat) {
|
||||
super.init(frame: CGRect())
|
||||
self.lineThickness = lineThickness
|
||||
}
|
||||
|
||||
@objc override open func setupView() {
|
||||
|
||||
defaultState()
|
||||
}
|
||||
|
||||
@ -48,7 +59,6 @@ open class CaretView: MFView {
|
||||
//------------------------------------------------------
|
||||
|
||||
private func defaultState() {
|
||||
|
||||
isOpaque = false
|
||||
isHidden = false
|
||||
backgroundColor = .clear
|
||||
@ -64,7 +74,7 @@ open class CaretView: MFView {
|
||||
let context = UIGraphicsGetCurrentContext()
|
||||
context?.clear(rect)
|
||||
|
||||
let lineWidthToDraw: CGFloat = lineWidth ?? frame.size.width / 2.6
|
||||
let lineWidthToDraw: CGFloat = lineWidth ?? frame.size.width / (lineThickness ?? 2.6)
|
||||
|
||||
let path = UIBezierPath()
|
||||
path.move(to: CGPoint(x: lineWidthToDraw / 2.0, y: 0.0))
|
||||
@ -80,7 +90,6 @@ open class CaretView: MFView {
|
||||
}
|
||||
|
||||
@objc public func setLineColor(_ color: UIColor?) {
|
||||
|
||||
strokeColor = color
|
||||
setNeedsDisplay()
|
||||
}
|
||||
@ -91,34 +100,40 @@ open class CaretView: MFView {
|
||||
|
||||
// Default values for view.
|
||||
@objc open override func setAsMolecule() {
|
||||
|
||||
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 }
|
||||
guard let dictionary = json else { return }
|
||||
|
||||
if let backgroundColorHex = jsonDictionary[KeyBackgroundColor] as? String {
|
||||
if let backgroundColorHex = dictionary[KeyBackgroundColor] as? String {
|
||||
backgroundColor = UIColor.mfGet(forHex: backgroundColorHex)
|
||||
}
|
||||
|
||||
if let strokeColorHex = jsonDictionary["strokeColor"] as? String {
|
||||
if let strokeColorHex = dictionary["strokeColor"] as? String {
|
||||
strokeColor = UIColor.mfGet(forHex: strokeColorHex)
|
||||
}
|
||||
|
||||
if let isHiddenValue = jsonDictionary[KeyIsHidden] as? Bool {
|
||||
if let isHiddenValue = dictionary[KeyIsHidden] as? Bool {
|
||||
isHidden = isHiddenValue
|
||||
}
|
||||
|
||||
if let isOpaqueValue = jsonDictionary[KeyIsOpaque] as? Bool {
|
||||
if let isOpaqueValue = dictionary[KeyIsOpaque] as? Bool {
|
||||
isOpaque = isOpaqueValue
|
||||
}
|
||||
|
||||
if let lineWidthValue = jsonDictionary["lineWidth"] as? CGFloat {
|
||||
if let lineWidthValue = dictionary["lineWidth"] as? CGFloat {
|
||||
lineWidth = lineWidthValue
|
||||
}
|
||||
}
|
||||
|
||||
open override func needsToBeConstrained() -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
open override func moleculeAlignment() -> UIStackView.Alignment {
|
||||
return UIStackView.Alignment.leading;
|
||||
}
|
||||
}
|
||||
|
||||
@ -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 }
|
||||
|
||||
310
MVMCoreUI/Atoms/Views/Label.swift
Normal file
310
MVMCoreUI/Atoms/Views/Label.swift
Normal file
@ -0,0 +1,310 @@
|
||||
//
|
||||
// Label.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 3/22/17.
|
||||
// Converted by Christiano, Kevin on 4/2/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import MVMCore
|
||||
|
||||
|
||||
@objc open class Label: UILabel, MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol {
|
||||
//------------------------------------------------------
|
||||
// MARK: - Properties
|
||||
//------------------------------------------------------
|
||||
|
||||
// Set this property if you want updateView to update the font based on this standard and the size passed in.
|
||||
@objc public var standardFontSize: CGFloat = 0.0
|
||||
|
||||
// Set this to use a custom sizing object during updateView instead of the standard.
|
||||
@objc public var sizeObject: MFSizeObject?
|
||||
|
||||
@objc public var scaleSize: NSNumber?
|
||||
|
||||
// Used for scaling the font in updateView.
|
||||
private var originalAttributedString: NSAttributedString?
|
||||
|
||||
@objc public var hasText: Bool {
|
||||
guard let text = text, let attributedText = attributedText else { return false }
|
||||
return !text.isEmpty || !attributedText.string.isEmpty
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Initialization
|
||||
//------------------------------------------------------
|
||||
|
||||
@objc public func setupView() {
|
||||
|
||||
backgroundColor = .clear
|
||||
numberOfLines = 0
|
||||
lineBreakMode = .byWordWrapping
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
}
|
||||
|
||||
@objc public init() {
|
||||
super.init(frame: .zero)
|
||||
setupView()
|
||||
}
|
||||
|
||||
@objc required public init?(coder: NSCoder) {
|
||||
super.init(coder: coder)
|
||||
setupView()
|
||||
}
|
||||
|
||||
@objc override public init(frame: CGRect) {
|
||||
super.init(frame: frame)
|
||||
setupView()
|
||||
}
|
||||
|
||||
@objc convenience public init(standardFontSize size: CGFloat) {
|
||||
self.init()
|
||||
standardFontSize = size
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Functions
|
||||
//------------------------------------------------------
|
||||
|
||||
@objc public static func commonLabelH1(_ scale: Bool) -> Label {
|
||||
let label = Label.label()
|
||||
label.styleH1(scale)
|
||||
return label
|
||||
}
|
||||
|
||||
@objc public static func commonLabelH2(_ scale: Bool) -> Label {
|
||||
let label = Label.label()
|
||||
label.styleH2(scale)
|
||||
return label
|
||||
}
|
||||
|
||||
@objc public static func commonLabelH3(_ scale: Bool) -> Label {
|
||||
let label = Label.label()
|
||||
label.styleH3(scale)
|
||||
return label
|
||||
}
|
||||
|
||||
@objc public static func commonLabelH32(_ scale: Bool) -> Label {
|
||||
let label = Label.label()
|
||||
label.styleH32(scale)
|
||||
return label
|
||||
}
|
||||
|
||||
@objc public static func commonLabelB1(_ scale: Bool) -> Label {
|
||||
let label = Label.label()
|
||||
label.styleB1(scale)
|
||||
return label
|
||||
}
|
||||
|
||||
@objc public static func commonLabelB2(_ scale: Bool) -> Label {
|
||||
let label = Label.label()
|
||||
label.styleB2(scale)
|
||||
return label
|
||||
}
|
||||
|
||||
@objc public static func commonLabelB3(_ scale: Bool) -> Label {
|
||||
let label = Label.label()
|
||||
label.styleB3(scale)
|
||||
return label
|
||||
}
|
||||
|
||||
@objc public static func commonLabelB20(_ scale: Bool) -> Label {
|
||||
let label = Label.label()
|
||||
label.styleB20(scale)
|
||||
return label
|
||||
}
|
||||
|
||||
@objc open class func label() -> Label {
|
||||
return Label(frame: .zero)
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Functions
|
||||
//------------------------------------------------------
|
||||
|
||||
@objc public static func setLabel(_ label: UILabel?, withHTML html: String?) {
|
||||
|
||||
guard let data = html?.data(using: .utf8) else { return }
|
||||
|
||||
do {
|
||||
label?.attributedText = try NSAttributedString(data: data,
|
||||
options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html,
|
||||
NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue],
|
||||
documentAttributes: nil)
|
||||
} catch {
|
||||
if let coreErrorObject = MVMCoreErrorObject.createErrorObject(for: error, location: "LabelHTMLParse") {
|
||||
MVMCoreUILoggingHandler.shared()?.addError(toLog: coreErrorObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@objc public static func setUILabel(_ label: UILabel?, withJSON json: [AnyHashable: Any]?, delegate: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
guard let label = label else { return }
|
||||
|
||||
label.text = json?.optionalStringForKey(KeyText)
|
||||
|
||||
setLabel(label, withHTML: json?.optionalStringForKey("html"))
|
||||
|
||||
if let textColorHex = json?.optionalStringForKey(KeyTextColor), !textColorHex.isEmpty {
|
||||
label.textColor = UIColor.mfGet(forHex: textColorHex)
|
||||
}
|
||||
|
||||
if let backgroundColorHex = json?.optionalStringForKey(KeyBackgroundColor), !backgroundColorHex.isEmpty {
|
||||
label.backgroundColor = UIColor.mfGet(forHex: backgroundColorHex)
|
||||
}
|
||||
|
||||
label.accessibilityLabel = json?.optionalStringForKey("accessibilityText")
|
||||
|
||||
let fontSize = json?["fontSize"] as? CGFloat
|
||||
|
||||
if let fontName = json?.optionalStringForKey("fontName") {
|
||||
label.font = MFFonts.mfFont(withName: fontName, size: fontSize ?? label.font.pointSize)
|
||||
} else if let fontSize = fontSize {
|
||||
label.font = label.font.withSize(fontSize)
|
||||
}
|
||||
|
||||
if let attributes = json?.arrayForKey("attributes"), let labelText = label.text {
|
||||
let attributedString = NSMutableAttributedString(string: labelText, attributes: [NSAttributedString.Key.font: label.font as UIFont,
|
||||
NSAttributedString.Key.foregroundColor: label.textColor as UIColor])
|
||||
for case let attribute as [String: Any] in attributes {
|
||||
|
||||
guard let attributeType = attribute.optionalStringForKey(KeyType),
|
||||
let location = attribute["location"] as? Int,
|
||||
let length = attribute["length"] as? Int
|
||||
else { continue }
|
||||
|
||||
let range = NSRange(location: location, length: length)
|
||||
|
||||
switch attributeType {
|
||||
case "underline":
|
||||
attributedString.addAttribute(.underlineStyle, value: NSUnderlineStyle.single.rawValue, range: range)
|
||||
|
||||
case "strikethrough":
|
||||
attributedString.addAttribute(.strikethroughStyle, value: NSUnderlineStyle.thick.rawValue, range: range)
|
||||
|
||||
case "color":
|
||||
if let colorHex = attribute.optionalStringForKey(KeyTextColor), !colorHex.isEmpty {
|
||||
attributedString.removeAttribute(.foregroundColor, range: range)
|
||||
attributedString.addAttribute(.foregroundColor, value: UIColor.mfGet(forHex: colorHex), range: range)
|
||||
}
|
||||
case "font":
|
||||
let fontSize = attribute["size"] as? CGFloat
|
||||
var font: UIFont?
|
||||
|
||||
if let fontName = attribute.optionalStringForKey("name") {
|
||||
font = MFFonts.mfFont(withName: fontName, size: fontSize ?? label.font.pointSize)
|
||||
} else if let fontSize = fontSize {
|
||||
font = label.font.withSize(fontSize)
|
||||
}
|
||||
|
||||
if let font = font {
|
||||
attributedString.removeAttribute(.font, range: range)
|
||||
attributedString.addAttribute(.font, value: font, range: range)
|
||||
}
|
||||
default:
|
||||
continue
|
||||
}
|
||||
}
|
||||
label.attributedText = attributedString
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Methods
|
||||
//------------------------------------------------------
|
||||
|
||||
@objc public func styleH1(_ scale: Bool) {
|
||||
MFStyler.styleLabelH1(self, genericScaling: false)
|
||||
setScale(scale)
|
||||
}
|
||||
|
||||
@objc public func styleH2(_ scale: Bool) {
|
||||
MFStyler.styleLabelH2(self, genericScaling: false)
|
||||
setScale(scale)
|
||||
}
|
||||
|
||||
@objc public func styleH3(_ scale: Bool) {
|
||||
MFStyler.styleLabelH3(self, genericScaling: false)
|
||||
setScale(scale)
|
||||
}
|
||||
|
||||
@objc public func styleH32(_ scale: Bool) {
|
||||
MFStyler.styleLabelH32(self, genericScaling: false)
|
||||
setScale(scale)
|
||||
}
|
||||
|
||||
@objc public func styleB1(_ scale: Bool) {
|
||||
MFStyler.styleLabelB1(self, genericScaling: false)
|
||||
setScale(scale)
|
||||
}
|
||||
|
||||
@objc public func styleB2(_ scale: Bool) {
|
||||
MFStyler.styleLabelB2(self, genericScaling: false)
|
||||
setScale(scale)
|
||||
}
|
||||
|
||||
@objc public func styleB3(_ scale: Bool) {
|
||||
MFStyler.styleLabelB3(self, genericScaling: false)
|
||||
setScale(scale)
|
||||
}
|
||||
|
||||
@objc public func styleB20(_ scale: Bool) {
|
||||
MFStyler.styleLabelB20(self, genericScaling: false)
|
||||
setScale(scale)
|
||||
}
|
||||
|
||||
@objc public func updateView(_ size: CGFloat) {
|
||||
scaleSize = size as NSNumber
|
||||
|
||||
if let originalAttributedString = originalAttributedString {
|
||||
let attributedString = NSMutableAttributedString(attributedString: originalAttributedString)
|
||||
attributedString.removeAttribute(.font, range: NSRange(location: 0, length: attributedString.length))
|
||||
originalAttributedString.enumerateAttribute(.font, in: NSRange(location: 0, length: originalAttributedString.length), options: [], using: { value, range, stop in
|
||||
// Loop the original attributed string, resize the fonts.
|
||||
if let fontObj = value as? UIFont, let stylerSize = MFStyler.sizeObjectGeneric(forCurrentDevice: fontObj.pointSize)?.getValueBased(onSize: size) {
|
||||
attributedString.addAttribute(.font, value: fontObj.withSize(stylerSize) as Any, range: range)
|
||||
}
|
||||
})
|
||||
attributedText = attributedString
|
||||
} else if !MVMCoreGetterUtility.fequal(a: Float(standardFontSize), b: 0.0), let sizeObject: MFSizeObject = self.sizeObject ?? MFStyler.sizeObjectGeneric(forCurrentDevice: standardFontSize) {
|
||||
self.font = self.font.withSize(sizeObject.getValueBased(onSize: size))
|
||||
}
|
||||
}
|
||||
|
||||
@objc public func setFont(_ font: UIFont, scale: Bool) {
|
||||
self.font = font
|
||||
setScale(scale)
|
||||
}
|
||||
|
||||
@objc public func setScale(_ scale: Bool) {
|
||||
if scale {
|
||||
standardFontSize = font.pointSize
|
||||
if let floatScale = scaleSize?.floatValue {
|
||||
updateView(CGFloat(floatScale))
|
||||
} else {
|
||||
updateView(MVMCoreUISplitViewController.getApplicationViewWidth())
|
||||
}
|
||||
} else {
|
||||
standardFontSize = 0
|
||||
}
|
||||
}
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Atomization
|
||||
//------------------------------------------------------
|
||||
|
||||
@objc public func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
Label.setUILabel(self, withJSON: json, delegate: delegateObject, additionalData: additionalData)
|
||||
originalAttributedString = attributedText
|
||||
}
|
||||
|
||||
public func needsToBeConstrained() -> Bool {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
extension Label {
|
||||
|
||||
}
|
||||
@ -8,12 +8,12 @@
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MVMCoreUI/ViewConstrainingView.h>
|
||||
#import <MVMCoreUI/MFLabel.h>
|
||||
@class Label;
|
||||
|
||||
@interface LabelView : ViewConstrainingView
|
||||
|
||||
// Customize the label.
|
||||
@property (nullable, weak, nonatomic) MFLabel *label;
|
||||
@property (nullable, weak, nonatomic) Label *label;
|
||||
|
||||
// Change the alignment of the label
|
||||
- (void)alignLeft;
|
||||
|
||||
@ -8,6 +8,7 @@
|
||||
|
||||
#import <MVMCoreUI/LabelView.h>
|
||||
#import "MFStyler.h"
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
@interface LabelView ()
|
||||
|
||||
// Change to customize.
|
||||
@ -32,7 +33,7 @@
|
||||
if (!self.label) {
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
|
||||
MFLabel *label = [MFLabel commonLabelB2:YES];
|
||||
Label *label = [Label commonLabelB2:YES];
|
||||
[self addSubview:label];
|
||||
self.label = label;
|
||||
|
||||
@ -72,9 +73,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 {
|
||||
|
||||
@ -10,9 +10,9 @@
|
||||
import MVMCore
|
||||
|
||||
public typealias ActionBlock = () -> Void
|
||||
private typealias ActionIndiciesTuple = (startIndex: String.Index?, endIndex: String.Index?, revisedText: String?)
|
||||
public typealias ActionObjectDelegate = (NSObjectProtocol & MVMCoreActionDelegateProtocol)
|
||||
public typealias ButtonObjectDelegate = (NSObjectProtocol & ButtonDelegateProtocol)
|
||||
private typealias ActionableStringTuple = (front: String?, action: String?, end: String?)
|
||||
public typealias ActionObjectDelegate = NSObjectProtocol & MVMCoreActionDelegateProtocol
|
||||
public typealias ButtonObjectDelegate = NSObjectProtocol & ButtonDelegateProtocol
|
||||
public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProtocol & MVMCoreLoadDelegateProtocol & MVMCorePresentationDelegateProtocol & NSObjectProtocol
|
||||
|
||||
|
||||
@ -22,11 +22,11 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
//------------------------------------------------------
|
||||
|
||||
public var actionBlock: ActionBlock?
|
||||
public weak var label: MFLabel?
|
||||
public weak var label: Label?
|
||||
|
||||
public var attributedText: NSAttributedString? {
|
||||
willSet(newAttributedText) {
|
||||
if let newAttribText = newAttributedText, !newAttribText.string.isEmpty {
|
||||
if let newAttribText = newAttributedText {
|
||||
|
||||
let mutableAttributedText = NSMutableAttributedString(attributedString: newAttribText)
|
||||
let paragraphStyle = NSMutableParagraphStyle()
|
||||
@ -62,6 +62,10 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
}
|
||||
}
|
||||
|
||||
private var actionRange: NSRange {
|
||||
return NSRange(location: frontText?.count ?? 0, length: actionText?.count ?? 0)
|
||||
}
|
||||
|
||||
public var makeWholeViewClickable = false
|
||||
|
||||
override open var isEnabled: Bool {
|
||||
@ -74,9 +78,16 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
public var actionText: String?
|
||||
public var backText: String?
|
||||
|
||||
private var text: String? {
|
||||
willSet(newText) {
|
||||
attributedText = NSAttributedString(string: newText ?? "")
|
||||
private var internalText: String = ""
|
||||
|
||||
public var text: String? {
|
||||
get {
|
||||
return internalText
|
||||
}
|
||||
set {
|
||||
guard let text = newValue else { return }
|
||||
internalText = text
|
||||
attributedText = NSAttributedString(string: text)
|
||||
setAlternateNormalTextAttributes([NSAttributedString.Key.font: normalTextFont as Any])
|
||||
setAlternateActionTextAttributes([NSAttributedString.Key.font: actionTextFont as Any])
|
||||
setAlternateNormalTextAttributes([NSAttributedString.Key.foregroundColor: normalTextColor as Any])
|
||||
@ -89,7 +100,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
//------------------------------------------------------
|
||||
|
||||
public init() {
|
||||
super.init(frame: CGRect.zero)
|
||||
super.init(frame: .zero)
|
||||
setup()
|
||||
}
|
||||
|
||||
@ -103,15 +114,9 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
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)
|
||||
super.init(frame: .zero)
|
||||
|
||||
self.frontText = frontText
|
||||
self.actionText = actionText
|
||||
@ -121,42 +126,46 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
setup()
|
||||
}
|
||||
|
||||
public convenience init(actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) {
|
||||
public convenience init(actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
self.init(frontText: actionMap?.optionalStringForKey(KeyTitlePrefix),
|
||||
actionText: actionMap?.optionalStringForKey(KeyTitle),
|
||||
backText: actionMap?.optionalStringForKey(KeyTitlePostfix),
|
||||
actionMap: actionMap, additionalData: additionalData,
|
||||
delegateObject: delegateObject)
|
||||
}
|
||||
|
||||
public convenience init(frontText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
self.init(frontText: frontText,
|
||||
actionText: actionMap?.optionalStringForKey(KeyTitle),
|
||||
backText: backText,
|
||||
actionMap: actionMap,
|
||||
additionalData: additionalData,
|
||||
delegateObject: delegateObject)
|
||||
}
|
||||
|
||||
public init(frontText: String?, actionText: String?, backText: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
super.init(frame: CGRect.zero)
|
||||
|
||||
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)
|
||||
setFrontText(frontText, actionText: actionText, actionMap: actionMap, backText: backText, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
|
||||
// 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 convenience init(clickableTextEmbeddedInCurlyBraces fullText: String?, actionMapForClickableText actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
self.init(text: fullText,
|
||||
startTag: "{",
|
||||
endTag: "}",
|
||||
actionMap: actionMap,
|
||||
additionalData: additionalData,
|
||||
delegateObject: delegateObject)
|
||||
}
|
||||
|
||||
public init(text fullText: String?, startTag: String?, endTag: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) {
|
||||
public init(text fullText: String?, startTag: String?, endTag: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
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)
|
||||
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
}
|
||||
|
||||
@ -167,7 +176,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
private func setup() {
|
||||
|
||||
if self.label == nil {
|
||||
let label = MFLabel(frame: CGRect.zero)
|
||||
let label = Label(frame: CGRect.zero)
|
||||
|
||||
backgroundColor = .clear
|
||||
label.isUserInteractionEnabled = false
|
||||
@ -186,13 +195,11 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
self.label?.attributedText = attributedText
|
||||
self.label?.accessibilityTraits = .button
|
||||
}
|
||||
|
||||
private func
|
||||
setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) {
|
||||
|
||||
@objc public func setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
|
||||
weak var weakSelf: LabelWithInternalButton? = self
|
||||
weak var weakDelegate: ActionObjectDelegate? = delegate
|
||||
weak var weakButtonDelegate: ButtonObjectDelegate? = buttonDelegate
|
||||
weak var weakButtonDelegate: ButtonDelegateProtocol? = (delegateObject as? MVMCoreUIDelegateObject)?.buttonDelegate
|
||||
|
||||
actionBlock = {
|
||||
var performAction = true
|
||||
@ -201,8 +208,8 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
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)
|
||||
if performAction {
|
||||
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -211,26 +218,22 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
// 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?) {
|
||||
@objc public func setFrontText(_ frontText: String?, actionText: String?, actionMap: [AnyHashable: Any]?, backText: String?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
|
||||
self.frontText = frontText
|
||||
setActionMap(actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: buttonDelegate)
|
||||
setActionMap(actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
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?) {
|
||||
@objc public func setFrontText(_ frontText: String?, actionMap: [AnyHashable: Any]?, backText: String?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
|
||||
setFrontAttributedText(frontAttributedText, actionMap: actionMap, backAttributedText: backText, addNewLine: false, additionalData: additionalData, delegate: delegate, buttonDelegate: buttonDelegate)
|
||||
setFrontText(frontText, actionText: actionMap?.optionalStringForKey(KeyTitle), actionMap: actionMap, backText: backText, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
|
||||
private func setFrontAttributedText(_ frontAttributedText: NSAttributedString?, actionMap: [AnyHashable: Any]?, backAttributedText: NSAttributedString?, addNewLine: Bool, additionalData: [AnyHashable: Any]?, delegate: ActionObjectDelegate?, buttonDelegate: ButtonObjectDelegate?) {
|
||||
@objc public func setFrontAttributedText(_ frontAttributedText: NSAttributedString?, actionMap: [AnyHashable: Any]?, backAttributedText: NSAttributedString?, addNewLine: Bool, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
|
||||
let mutableAttributedString = NSMutableAttributedString()
|
||||
|
||||
@ -248,7 +251,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
|
||||
let actionStringOnLine = actionString + (addNewLine ? "\n" : " ")
|
||||
actionText = actionStringOnLine
|
||||
setActionMap(actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: buttonDelegate)
|
||||
setActionMap(actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
mutableAttributedString.append(MFStyler.styleGetAttributedString(actionStringOnLine, font: b2Font, color: .black))
|
||||
|
||||
} else {
|
||||
@ -297,7 +300,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
|
||||
let location: CGPoint? = touches?.first?.location(in: label)
|
||||
let actionString = actionText
|
||||
let index: Int = getActionRange().location
|
||||
let index: Int = actionRange.location
|
||||
let rangeArray = getRangeArrayOfWords(in: actionString, withInitalIndex: index)
|
||||
let rectArray = getRectArray(fromRangeArray: rangeArray)
|
||||
var result = false
|
||||
@ -335,11 +338,6 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
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
|
||||
@ -381,71 +379,66 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
|
||||
private func setText(_ text: String?, startTag: String?, endTag: String?) {
|
||||
|
||||
let actionRange: ActionIndiciesTuple = rangeOfText(text, startTag: startTag, endTag: endTag)
|
||||
let actionableTuple: ActionableStringTuple = rangeOfText(text, startTag: startTag, endTag: endTag)
|
||||
|
||||
if let revisedText = actionRange.revisedText, let startBraceIndex = actionRange.startIndex, let endBraceIndex = actionRange.endIndex {
|
||||
if let text = text,
|
||||
let leftTag = startTag,
|
||||
text.contains(leftTag),
|
||||
let rightTag = endTag,
|
||||
text.contains(rightTag),
|
||||
let front = actionableTuple.front,
|
||||
let middle = actionableTuple.action,
|
||||
let end = actionableTuple.end {
|
||||
|
||||
frontText = String(revisedText[revisedText.startIndex..<startBraceIndex]).trimmingCharacters(in: .whitespaces)
|
||||
actionText = String(revisedText[startBraceIndex..<endBraceIndex]).trimmingCharacters(in: .whitespaces)
|
||||
backText = String(revisedText[endBraceIndex...]).trimmingCharacters(in: .whitespaces)
|
||||
self.text = getTextFromStringComponents()
|
||||
frontText = front.trimmingCharacters(in: .whitespaces)
|
||||
actionText = middle.trimmingCharacters(in: .whitespaces)
|
||||
backText = end.trimmingCharacters(in: .whitespaces)
|
||||
} else {
|
||||
frontText = actionRange.revisedText
|
||||
self.text = actionRange.revisedText
|
||||
frontText = text
|
||||
}
|
||||
|
||||
self.text = getTextFromStringComponents()
|
||||
setup()
|
||||
}
|
||||
|
||||
private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> ActionIndiciesTuple {
|
||||
private func rangeOfText(_ text: String?, startTag: String?, endTag: String?) -> ActionableStringTuple {
|
||||
|
||||
var fullText = text ?? ""
|
||||
var actionRange: ActionIndiciesTuple = (startIndex: nil, endIndex: nil, revisedText: nil)
|
||||
var actionableTuple: ActionableStringTuple = (front: nil, action: nil, end: nil)
|
||||
|
||||
if let leftBrace = startTag, let rightBrace = endTag, fullText.contains(Character(leftBrace)) && fullText.contains(Character(rightBrace)) {
|
||||
actionRange.startIndex = fullText.firstIndex(of: Character(leftBrace))
|
||||
fullText = fullText.replacingOccurrences(of: leftBrace, with: "")
|
||||
guard let text = text else { return actionableTuple }
|
||||
|
||||
if let leftTag = startTag, text.contains(leftTag) {
|
||||
|
||||
actionRange.endIndex = fullText.firstIndex(of: Character(rightBrace))
|
||||
fullText = fullText.replacingOccurrences(of: rightBrace, with: "")
|
||||
let firstHalf = text.components(separatedBy: leftTag)
|
||||
actionableTuple.front = firstHalf.first
|
||||
|
||||
if let rightTag = endTag, text.contains(rightTag) {
|
||||
let secondHalf = firstHalf[1].components(separatedBy: rightTag)
|
||||
actionableTuple.action = secondHalf[0]
|
||||
actionableTuple.end = secondHalf[1]
|
||||
}
|
||||
}
|
||||
|
||||
actionRange.revisedText = fullText
|
||||
return actionRange
|
||||
}
|
||||
|
||||
@objc public func setActionMap(_ actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) {
|
||||
|
||||
setActionMap(actionMap, additionalData: additionalData, actionDelegate: delegate, buttonDelegate: nil)
|
||||
return actionableTuple
|
||||
}
|
||||
|
||||
// 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?) {
|
||||
@objc public func setTextWithClickableTextEmbeddedInCurlyBraces(_ text: String?, textAttributes attributes: [AnyHashable: Any]?, actionMapForClickableText actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
|
||||
attributedText = NSAttributedString(string: text ?? "", attributes: attributes as? [NSAttributedString.Key: Any])
|
||||
setActionMap(actionMap, additionalData: additionalData, actionDelegate: delegate)
|
||||
setActionMap(actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
|
||||
@objc public func setWithText(_ fullText: String?, startTag: String?, endTag: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, actionDelegate delegate: ActionObjectDelegate?) {
|
||||
@objc public func setWithText(_ fullText: String?, startTag: String?, endTag: String?, actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
|
||||
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)
|
||||
setActionMap(actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
|
||||
// Reset the front text, back text, action map
|
||||
@objc public func setFrontAttributedText(_ frontAttributedText: NSAttributedString?, actionMap: [AnyHashable: Any]?, backAttributedText: NSAttributedString?, additionalData: [AnyHashable: Any]?, delegate: ActionObjectDelegate?) {
|
||||
@objc public func setFrontAttributedText(_ frontAttributedText: NSAttributedString?, actionMap: [AnyHashable: Any]?, backAttributedText: NSAttributedString?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
|
||||
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)
|
||||
setFrontAttributedText(frontAttributedText, actionMap: actionMap, backAttributedText: backAttributedText, addNewLine: false, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
|
||||
@objc public func setAlignment(_ textAlignment: NSTextAlignment) {
|
||||
@ -459,7 +452,7 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
let attributedString = NSMutableAttributedString(attributedString: thisAttributedText)
|
||||
|
||||
if !attributedString.string.isEmpty {
|
||||
attributedString.addAttributes(theseAttributes, range: getActionRange())
|
||||
attributedString.addAttributes(theseAttributes, range: actionRange)
|
||||
}
|
||||
attributedText = attributedString
|
||||
}
|
||||
@ -497,16 +490,14 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
}
|
||||
|
||||
/// Used to just reset the texts and actions if already initialized
|
||||
@objc public func reset(withActionMap actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegate: ActionObjectDelegate?) {
|
||||
@objc public func reset(withActionMap actionMap: [AnyHashable: Any]?, additionalData: [AnyHashable: Any]?, delegateObject: DelegateObject?) {
|
||||
|
||||
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)
|
||||
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegateObject: delegateObject)
|
||||
}
|
||||
|
||||
text = getTextFromStringComponents()
|
||||
@ -541,20 +532,209 @@ public typealias CoreObjectActionLoadPresentDelegate = MVMCoreActionDelegateProt
|
||||
|
||||
return UIAccessibilityCustomAction()
|
||||
}
|
||||
}
|
||||
|
||||
extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol {
|
||||
|
||||
//------------------------------------------------------
|
||||
// MARK: - Atomization
|
||||
// MARK: - Legacy for Delegate Change
|
||||
//------------------------------------------------------
|
||||
|
||||
@available(*, deprecated)
|
||||
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)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
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)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
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)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
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)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
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)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
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 {}.
|
||||
@available(*, deprecated)
|
||||
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)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
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 performAction {
|
||||
MVMCoreActionHandler.shared()?.handleAction(with: actionMap, additionalData: additionalData, delegate: weakDelegate as? CoreObjectActionLoadPresentDelegate)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
@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)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
@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()
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
@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)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
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)])
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
@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
|
||||
@available(*, deprecated)
|
||||
@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)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
@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)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
@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
|
||||
@available(*, deprecated)
|
||||
@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)
|
||||
}
|
||||
|
||||
@available(*, deprecated)
|
||||
@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)
|
||||
}
|
||||
|
||||
/// Used to just reset the texts and actions if already initialized
|
||||
@available(*, deprecated)
|
||||
@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: - Atomization
|
||||
extension LabelWithInternalButton: MVMCoreUIMoleculeViewProtocol {
|
||||
// Default values for view.
|
||||
@objc open func setAsMolecule() {
|
||||
|
||||
}
|
||||
|
||||
@objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegate: NSObject?, additionalData: [AnyHashable: Any]?) {
|
||||
|
||||
@objc open func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
// Configure class properties with JSON values
|
||||
guard let dictionary = json else { return }
|
||||
|
||||
|
||||
@ -1,63 +0,0 @@
|
||||
//
|
||||
// MFLabel.h
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Scott Pfeil on 3/22/17.
|
||||
// Copyright © 2017 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MVMCoreUI/MFView.h>
|
||||
@class MFSizeObject;
|
||||
|
||||
@interface MFLabel : UILabel <MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol>
|
||||
|
||||
- (nullable instancetype)initWithStandardFontSize:(CGFloat)size;
|
||||
|
||||
// Set this property if you want updateView to update the font based on this standard and the size passed in.
|
||||
@property (nonatomic) CGFloat standardFontSize;
|
||||
|
||||
// Set this to use a custom sizing object during updateView instead of the standard.
|
||||
@property (nonatomic, strong, nullable) MFSizeObject *sizeObject;
|
||||
|
||||
// Set the font and set to scale
|
||||
- (void)setFont:(nonnull UIFont *)font scale:(BOOL)scale;
|
||||
|
||||
// Convenience checker for text or attributed text.
|
||||
- (BOOL)hasText;
|
||||
|
||||
#pragma mark - 2.0
|
||||
//75Bd 40pt
|
||||
+ (nonnull MFLabel *)commonLabelH1:(BOOL)scale;
|
||||
//75Bd 25pt
|
||||
+ (nonnull MFLabel *)commonLabelH2:(BOOL)scale;
|
||||
//75Bd 18pt
|
||||
+ (nonnull MFLabel *)commonLabelH3:(BOOL)scale;
|
||||
//75Bd 32pt
|
||||
+ (nonnull MFLabel *)commonLabelH32:(BOOL)scale;
|
||||
//75Bd 13pt
|
||||
+ (nonnull MFLabel *)commonLabelB1:(BOOL)scale;
|
||||
//55Rg 13pt
|
||||
+ (nonnull MFLabel *)commonLabelB2:(BOOL)scale;
|
||||
//55Rg 11pt gray
|
||||
+ (nonnull MFLabel *)commonLabelB3:(BOOL)scale;
|
||||
//55Rg 20pt
|
||||
+ (nonnull MFLabel *)commonLabelB20:(BOOL)scale;
|
||||
|
||||
// Getters
|
||||
+ (nonnull MFLabel *)label NS_SWIFT_NAME(commonLabel());
|
||||
|
||||
// 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)styleH1:(BOOL)scale;
|
||||
- (void)styleH2:(BOOL)scale;
|
||||
- (void)styleH3:(BOOL)scale;
|
||||
- (void)styleH32:(BOOL)scale;
|
||||
- (void)styleB1:(BOOL)scale;
|
||||
- (void)styleB2:(BOOL)scale;
|
||||
- (void)styleB3:(BOOL)scale;
|
||||
- (void)styleB20:(BOOL)scale;
|
||||
|
||||
@end
|
||||
@ -1,291 +0,0 @@
|
||||
//
|
||||
// MFLabel.m
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Scott Pfeil on 3/22/17.
|
||||
// Copyright © 2017 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import "MFLabel.h"
|
||||
#import <MVMCoreUI/MFStyler.h>
|
||||
#import <MVMCoreUI/MFSizeObject.h>
|
||||
#import <MVMCoreUI/MVMCoreUIConstants.h>
|
||||
#import "UIColor+MFConvenience.h"
|
||||
#import "MFFonts.h"
|
||||
#import "MVMCoreUISplitViewController.h"
|
||||
#import "MVMCoreUILoggingHandler.h"
|
||||
@import MVMCore.MVMCoreGetterUtility;
|
||||
@import MVMCore.NSDictionary_MFConvenience;
|
||||
@import MVMCore.MVMCoreJSONConstants;
|
||||
|
||||
@interface MFLabel ()
|
||||
|
||||
@property (strong, nonatomic) NSNumber *scaleSize;
|
||||
|
||||
// Used for scaling the font in updateView.
|
||||
@property (strong, nonatomic) NSAttributedString *originalAttributedString;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MFLabel
|
||||
|
||||
- (void)setupView {
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
self.numberOfLines = 0;
|
||||
self.lineBreakMode = NSLineBreakByWordWrapping;
|
||||
self.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
}
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
[self setupView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)coder {
|
||||
self = [super initWithCoder:coder];
|
||||
if (self) {
|
||||
[self setupView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self setupView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithStandardFontSize:(CGFloat)size {
|
||||
if ([self init]) {
|
||||
self.standardFontSize = size;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)updateView:(CGFloat)size {
|
||||
self.scaleSize = @(size);
|
||||
if (self.originalAttributedString) {
|
||||
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithAttributedString:self.originalAttributedString];
|
||||
[attributedString removeAttribute:NSFontAttributeName range:NSMakeRange(0, attributedString.length)];
|
||||
[self.originalAttributedString enumerateAttribute:NSFontAttributeName inRange:NSMakeRange(0, self.originalAttributedString.length) options:0 usingBlock:^(UIFont *value, NSRange range, BOOL * _Nonnull stop) {
|
||||
// Loop the original attributed string, resize the fonts.
|
||||
UIFont *font = [value fontWithSize:[[MFStyler sizeObjectGenericForCurrentDevice:value.pointSize] getValueBasedOnSize:size]];
|
||||
[attributedString addAttribute:NSFontAttributeName value:font range:range];
|
||||
}];
|
||||
self.attributedText = attributedString;
|
||||
} else if (!fequal(self.standardFontSize, 0)) {
|
||||
MFSizeObject *sizeObject = self.sizeObject;
|
||||
if (!sizeObject) {
|
||||
sizeObject = [MFStyler sizeObjectGenericForCurrentDevice:self.standardFontSize];
|
||||
}
|
||||
self.font = [self.font fontWithSize:[sizeObject getValueBasedOnSize:size]];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setFont:(nonnull UIFont *)font scale:(BOOL)scale {
|
||||
self.font = font;
|
||||
[self setScale:scale];
|
||||
}
|
||||
|
||||
- (void)setScale:(BOOL)scale {
|
||||
if (scale) {
|
||||
self.standardFontSize = self.font.pointSize;
|
||||
[self updateView:(self.scaleSize ? self.scaleSize.floatValue : [MVMCoreUISplitViewController getApplicationViewWidth])];
|
||||
} else {
|
||||
self.standardFontSize = 0;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)hasText {
|
||||
return self.text.length > 0 || self.attributedText.length > 0;
|
||||
}
|
||||
|
||||
#pragma mark - 2.0
|
||||
|
||||
+ (nonnull MFLabel *)commonLabelH1:(BOOL)scale {
|
||||
MFLabel *label = [MFLabel label];
|
||||
[label styleH1:scale];
|
||||
return label;
|
||||
}
|
||||
|
||||
+ (nonnull MFLabel *)commonLabelH2:(BOOL)scale {
|
||||
MFLabel *label = [MFLabel label];
|
||||
[label styleH2:scale];
|
||||
return label;
|
||||
}
|
||||
|
||||
+ (nonnull MFLabel *)commonLabelH3:(BOOL)scale {
|
||||
MFLabel *label = [MFLabel label];
|
||||
[label styleH3:scale];
|
||||
return label;
|
||||
}
|
||||
+ (nonnull MFLabel *)commonLabelH32:(BOOL)scale {
|
||||
MFLabel *label = [MFLabel label];
|
||||
[label styleH32:scale];
|
||||
return label;
|
||||
}
|
||||
|
||||
+ (nonnull MFLabel *)commonLabelB1:(BOOL)scale {
|
||||
MFLabel *label = [MFLabel label];
|
||||
[label styleB1:scale];
|
||||
return label;
|
||||
}
|
||||
|
||||
+ (nonnull MFLabel *)commonLabelB2:(BOOL)scale {
|
||||
MFLabel *label = [MFLabel label];
|
||||
[label styleB2:scale];
|
||||
return label;
|
||||
}
|
||||
|
||||
+ (nonnull MFLabel *)commonLabelB3:(BOOL)scale {
|
||||
MFLabel *label = [MFLabel label];
|
||||
[label styleB3:scale];
|
||||
return label;
|
||||
}
|
||||
|
||||
+ (nonnull MFLabel *)commonLabelB20:(BOOL)scale {
|
||||
MFLabel *label = [MFLabel label];
|
||||
[label styleB20:scale];
|
||||
return label;
|
||||
}
|
||||
|
||||
+ (nonnull MFLabel *)label {
|
||||
return [[MFLabel alloc] initWithFrame:CGRectZero];
|
||||
}
|
||||
|
||||
#pragma mark - Setters
|
||||
|
||||
+ (void)setLabel:(nullable UILabel *)label withHTML:(nullable NSString *)html {
|
||||
NSData *data = [html dataUsingEncoding:kCFStringEncodingUTF8];
|
||||
if (data) {
|
||||
NSError *error = nil;
|
||||
label.attributedText = [[NSAttributedString alloc] initWithData:data options:@{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType} documentAttributes:nil error:&error];
|
||||
if (error) {
|
||||
[[MVMCoreUILoggingHandler sharedLoggingHandler] addErrorToLog:[MVMCoreErrorObject createErrorObjectForNSError:error location:@"LabelHTMLParse"]];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+ (void)setUILabel:(nullable UILabel *)label withJSON:(nullable NSDictionary *)json delegate:(nullable NSObject *)delegate additionalData:(nullable NSDictionary *)additionalData {
|
||||
if (label) {
|
||||
label.text = [json string:KeyText];
|
||||
[self setLabel:label withHTML:[json string:@"html"]];
|
||||
NSString *textColor = [json string:KeyTextColor];
|
||||
if (textColor) {
|
||||
label.textColor = [UIColor mfGetColorForHex:textColor];
|
||||
}
|
||||
NSString *backgroundColor = [json string:KeyBackgroundColor];
|
||||
if (backgroundColor) {
|
||||
label.backgroundColor = [UIColor mfGetColorForHex:backgroundColor];
|
||||
}
|
||||
NSString *accessibilityText = [json string:@"accessibilityText"];
|
||||
if (accessibilityText) {
|
||||
label.accessibilityLabel = accessibilityText;
|
||||
}
|
||||
NSString *fontName = [json string:@"fontName"];
|
||||
NSNumber *fontSize = [json optionalNumberForKey:@"fontSize"];
|
||||
if (fontName) {
|
||||
label.font = [MFFonts mfFontWithName:fontName size:fontSize ? fontSize.doubleValue : label.font.pointSize];
|
||||
} else if (fontSize) {
|
||||
label.font = [label.font fontWithSize:fontSize.doubleValue];
|
||||
}
|
||||
|
||||
NSArray *attributes = [json array:@"attributes"];
|
||||
if (attributes) {
|
||||
NSMutableAttributedString *attributedString = [[NSMutableAttributedString alloc] initWithString:label.text attributes:@{NSFontAttributeName:label.font,NSForegroundColorAttributeName:label.textColor}];
|
||||
for (NSDictionary *attribute in attributes) {
|
||||
NSNumber *location = [attribute optionalNumberForKey:@"location"];
|
||||
NSNumber *length = [attribute optionalNumberForKey:@"length"];
|
||||
if (location && length) {
|
||||
NSRange range = NSMakeRange(location.unsignedIntegerValue, length.unsignedIntegerValue);
|
||||
NSString *type = [attribute string:KeyType];
|
||||
if ([type isEqualToString:@"underline"]) {
|
||||
[attributedString addAttribute:NSUnderlineStyleAttributeName value:@(NSUnderlineStyleSingle) range:range];
|
||||
} else if ([type isEqualToString:@"strikethrough"]) {
|
||||
[attributedString addAttribute:NSStrikethroughStyleAttributeName value:@(NSUnderlineStyleThick) range:range];
|
||||
} else if ([type isEqualToString:@"color"]) {
|
||||
NSString *color = [attribute string:KeyTextColor];
|
||||
if (color) {
|
||||
[attributedString addAttribute:NSForegroundColorAttributeName value:[UIColor mfGetColorForHex:color] range:range];
|
||||
}
|
||||
} else if ([type isEqualToString:@"font"]) {
|
||||
NSString *fontName = [attribute string:@"name"];
|
||||
NSNumber *fontSize = [attribute optionalNumberForKey:@"size"];
|
||||
UIFont *font = nil;
|
||||
if (fontName) {
|
||||
font = [MFFonts mfFontWithName:fontName size:fontSize ? fontSize.doubleValue : label.font.pointSize];
|
||||
} else if (fontSize) {
|
||||
font = [label.font fontWithSize:fontSize.doubleValue];
|
||||
}
|
||||
if (font) {
|
||||
[attributedString addAttribute:NSFontAttributeName value:font range:range];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
label.attributedText = attributedString;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setWithJSON:(NSDictionary *)json delegate:(NSObject *)delegate additionalData:(NSDictionary *)additionalData {
|
||||
[MFLabel setUILabel:self withJSON:json delegate:delegate additionalData:additionalData];
|
||||
self.originalAttributedString = self.attributedText;
|
||||
}
|
||||
|
||||
- (void)styleH1:(BOOL)scale {
|
||||
[MFStyler styleLabelH1:self genericScaling:NO];
|
||||
[self setScale:scale];
|
||||
}
|
||||
|
||||
- (void)styleH2:(BOOL)scale {
|
||||
[MFStyler styleLabelH2:self genericScaling:NO];
|
||||
[self setScale:scale];
|
||||
}
|
||||
|
||||
- (void)styleH3:(BOOL)scale {
|
||||
[MFStyler styleLabelH3:self genericScaling:NO];
|
||||
[self setScale:scale];
|
||||
}
|
||||
|
||||
- (void)styleH32:(BOOL)scale {
|
||||
[MFStyler styleLabelH32:self genericScaling:NO];
|
||||
[self setScale:scale];
|
||||
}
|
||||
|
||||
- (void)styleB1:(BOOL)scale {
|
||||
[MFStyler styleLabelB1:self genericScaling:NO];
|
||||
[self setScale:scale];
|
||||
}
|
||||
|
||||
- (void)styleB2:(BOOL)scale {
|
||||
[MFStyler styleLabelB2:self genericScaling:NO];
|
||||
[self setScale:scale];
|
||||
}
|
||||
|
||||
- (void)styleB3:(BOOL)scale {
|
||||
[MFStyler styleLabelB3:self genericScaling:NO];
|
||||
[self setScale:scale];
|
||||
}
|
||||
|
||||
- (void)styleB20:(BOOL)scale {
|
||||
[MFStyler styleLabelB20:self genericScaling:NO];
|
||||
[self setScale:scale];
|
||||
}
|
||||
|
||||
- (void)setAccessibilityTraits:(UIAccessibilityTraits)accessibilityTraits {
|
||||
|
||||
if (accessibilityTraits& UIAccessibilityTraitHeader) {
|
||||
UIAccessibilityTraits noHeaderTraits = accessibilityTraits - UIAccessibilityTraitHeader;
|
||||
[super setAccessibilityTraits:noHeaderTraits];
|
||||
} else {
|
||||
[super setAccessibilityTraits:accessibilityTraits];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@end
|
||||
@ -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
|
||||
|
||||
@ -35,7 +36,7 @@
|
||||
}
|
||||
|
||||
- (void)setupView {
|
||||
|
||||
self.preservesSuperviewLayoutMargins = YES;
|
||||
}
|
||||
|
||||
- (void)updateView:(CGFloat)size {
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
||||
@ -9,7 +9,7 @@
|
||||
#import <UIKit/UIKit.h>
|
||||
#import <MVMCoreUI/MFView.h>
|
||||
#import <MVMCoreUI/MVMCoreUICheckMarkView.h>
|
||||
#import <MVMCoreUI/MFLabel.h>
|
||||
@class Label;
|
||||
@class MFSizeObject;
|
||||
|
||||
@interface MVMCoreUICheckBox : UIControl <MVMCoreViewProtocol>
|
||||
@ -23,7 +23,7 @@
|
||||
@property (nullable, strong, nonatomic) UIColor *unCheckedColor;
|
||||
|
||||
// Label to the right of the check box.
|
||||
@property (nullable, weak, nonatomic) MFLabel *descriptionLabel;
|
||||
@property (nullable, weak, nonatomic) Label *descriptionLabel;
|
||||
|
||||
// Setter for the descriptionLabel.text. Also sets the accessibility text.
|
||||
@property (nullable, strong, nonatomic) NSString *descriptionText;
|
||||
|
||||
@ -16,10 +16,12 @@
|
||||
#import "UIColor+MFConvenience.h"
|
||||
#import "MVMCoreUIUtility.h"
|
||||
#import "MFStyler.h"
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
|
||||
static const CGFloat FaultTolerance = 20.f;
|
||||
static const CGFloat CheckBoxHeightWidth = 18.0;
|
||||
@interface MVMCoreUICheckBox ()
|
||||
|
||||
@interface MVMCoreUICheckBox () <FormValidationProtocol, MVMCoreUIMoleculeViewProtocol>
|
||||
|
||||
@property (nonatomic, readwrite) BOOL isSelected;
|
||||
@property (weak, nonatomic) UIView *checkedSquare;
|
||||
@ -38,10 +40,45 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
|
||||
@property (nullable, strong, nonatomic) NSLayoutConstraint *checkboxWidth;
|
||||
@property (nullable, strong, nonatomic) NSLayoutConstraint *checkboxHeight;
|
||||
|
||||
@property (nonatomic) BOOL isRequired;
|
||||
@property (nullable, strong, nonatomic) NSString *fieldKey;
|
||||
@property (nullable, strong, nonatomic) DelegateObject *delegate;
|
||||
|
||||
@end
|
||||
|
||||
@implementation MVMCoreUICheckBox
|
||||
|
||||
#pragma mark - MVMCoreUIMoleculeViewProtocol
|
||||
|
||||
- (BOOL)needsToBeConstrained {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (UIStackViewAlignment)moleculeAlignment {
|
||||
return UIStackViewAlignmentLeading;
|
||||
}
|
||||
|
||||
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
|
||||
|
||||
[FormValidator setupValidationWithMolecule:self delegate:((MVMCoreUIDelegateObject *)delegateObject).formValidationProtocol];
|
||||
self.delegate = delegateObject;
|
||||
self.fieldKey = [json stringForKey:KeyFieldKey];
|
||||
self.isRequired = [json boolForKey:KeyRequired];
|
||||
|
||||
NSString *checkedColorHex = [json string:@"checkedColor"];
|
||||
NSString *unCheckedColorHex = [json string:@"unCheckedColor"];
|
||||
|
||||
UIColor *checkedColor = checkedColorHex ? [UIColor mfGetColorForHex:checkedColorHex]: [UIColor clearColor];
|
||||
UIColor *unCheckedColor = unCheckedColorHex ? [UIColor mfGetColorForHex:unCheckedColorHex]: [UIColor clearColor];
|
||||
|
||||
[self setupWithCheckedColor:checkedColor
|
||||
unCheckColor:unCheckedColor
|
||||
label:[json dict:KeyLabel]
|
||||
delegateObject:delegateObject
|
||||
additionalData: additionalData];
|
||||
}
|
||||
|
||||
|
||||
#pragma mark - convenient class methods
|
||||
|
||||
+ (instancetype)mfCheckBox {
|
||||
@ -68,8 +105,33 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
|
||||
return checkBox;
|
||||
}
|
||||
|
||||
#pragma mark - FormValidationProtocol
|
||||
|
||||
- (BOOL)isValidField {
|
||||
if (self.isRequired) {
|
||||
return self.isSelected;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
- (nullable NSString *)formFieldName {
|
||||
return self.fieldKey;
|
||||
}
|
||||
|
||||
- (nullable id)formFieldValue {
|
||||
return @(self.isSelected);
|
||||
}
|
||||
|
||||
#pragma mark - inits
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
[self setupView];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (instancetype)initWithCheckedColor:(UIColor *)checkedColor unCheckColor:(UIColor *)unCheckedColor text:(NSString *)text {
|
||||
if (self = [super init]) {
|
||||
[self setupWithCheckedColor:checkedColor unCheckColor:unCheckedColor text:text];
|
||||
@ -121,6 +183,7 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
|
||||
- (instancetype)initWithCoder:(NSCoder *)coder {
|
||||
self = [super initWithCoder:coder];
|
||||
if (self) {
|
||||
[self setupView];
|
||||
[self setupWithCheckedColor:[UIColor whiteColor] unCheckColor:[UIColor whiteColor] text:nil];
|
||||
[self addAccessibleProperties];
|
||||
}
|
||||
@ -130,6 +193,7 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
|
||||
- (instancetype)initWithFrame:(CGRect)frame {
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
[self setupView];
|
||||
[self setupWithCheckedColor:[UIColor whiteColor] unCheckColor:[UIColor whiteColor] text:nil];
|
||||
[self addAccessibleProperties];
|
||||
}
|
||||
@ -179,14 +243,12 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
|
||||
[self.checkMark.widthAnchor constraintEqualToAnchor:self.checkedSquare.widthAnchor multiplier:.4].active = YES;
|
||||
[self.checkMark.heightAnchor constraintEqualToAnchor:self.checkedSquare.heightAnchor multiplier:.4].active = YES;
|
||||
[self.checkMark.centerXAnchor constraintEqualToAnchor:self.checkedSquare.centerXAnchor].active = YES;
|
||||
[self.checkMark.centerYAnchor constraintEqualToAnchor:self.checkedSquare.centerYAnchor].active = YES;
|
||||
} else {
|
||||
[self.checkedSquare addSubview:self.checkMark];
|
||||
[self.checkMark.centerYAnchor constraintEqualToAnchor:self.checkedSquare.centerYAnchor].active = YES;
|
||||
}
|
||||
|
||||
//label
|
||||
if (!self.descriptionLabel) {
|
||||
MFLabel *descriptionLabel = [MFLabel commonLabelB2:YES];
|
||||
Label *descriptionLabel = [Label commonLabelB2:YES];
|
||||
[containterView addSubview:descriptionLabel];
|
||||
[NSLayoutConstraint constraintPinSubview:descriptionLabel pinCenterX:NO pinCenterY:YES];
|
||||
[NSLayoutConstraint constraintPinSubview:descriptionLabel pinTop:NO pinBottom:NO pinLeft:NO pinRight:YES];
|
||||
@ -206,17 +268,25 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setupWithCheckedColor:(UIColor *)checkedColor unCheckColor:(UIColor *)unCheckedColor {
|
||||
if (checkedColor) {
|
||||
self.checkedColor = checkedColor;
|
||||
}
|
||||
if (unCheckedColor) {
|
||||
self.unCheckedColor = unCheckedColor;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setupWithCheckedColor:(UIColor *)checkedColor unCheckColor:(UIColor *)unCheckedColor text:(NSString *)text {
|
||||
[self setupView];
|
||||
if (checkedColor) {
|
||||
self.checkedColor = checkedColor;
|
||||
}
|
||||
if (unCheckedColor) {
|
||||
self.unCheckedColor = unCheckedColor;
|
||||
}
|
||||
[self setupWithCheckedColor:checkedColor unCheckColor:unCheckedColor];
|
||||
[self setDescriptionText:text];
|
||||
}
|
||||
|
||||
- (void)setupWithCheckedColor:(UIColor *)checkedColor unCheckColor:(UIColor *)unCheckedColor label:(NSDictionary *)labelJson delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
|
||||
[self setupWithCheckedColor:checkedColor unCheckColor:unCheckedColor];
|
||||
[self.descriptionLabel setWithJSON:labelJson delegateObject:delegateObject additionalData:additionalData];
|
||||
}
|
||||
|
||||
- (void)updateView:(CGFloat)size {
|
||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||
[self.descriptionLabel updateView:size];
|
||||
@ -253,7 +323,7 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
|
||||
[self setSelected:selected animated:animated runBlock:YES];
|
||||
}
|
||||
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated runBlock:(BOOL)runBlock{
|
||||
- (void)setSelected:(BOOL)selected animated:(BOOL)animated runBlock:(BOOL)runBlock {
|
||||
[self addAccessibilityLabel:selected];
|
||||
|
||||
self.isSelected = selected;
|
||||
@ -271,6 +341,9 @@ static const CGFloat CheckBoxHeightWidth = 18.0;
|
||||
} completion:nil];
|
||||
[self.checkMark updateCheckSelected:NO animated:animated];
|
||||
}
|
||||
|
||||
FormValidator *formValidator = ((MVMCoreUIDelegateObject *)self.delegate).formValidationProtocol.formValidatorModel;
|
||||
[formValidator enableByValidation];
|
||||
}
|
||||
|
||||
- (void)setColor:(nullable UIColor *)color forState:(UIControlState)state {
|
||||
|
||||
@ -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];
|
||||
|
||||
@ -26,6 +26,9 @@
|
||||
// Returns a view with the provided view as a subview, pinned.
|
||||
+ (nonnull ViewConstrainingView *)viewConstrainingView:(nonnull UIView *)view;
|
||||
|
||||
// Can be initialized with a molecule to constrain
|
||||
- (nullable instancetype)initWithMolecule:(nonnull UIView <MVMCoreUIMoleculeViewProtocol>*)molecule alignment:(UIStackViewAlignment)alignment;
|
||||
|
||||
// Use these to sets the constants, because subclasses may align differently.
|
||||
- (void)setPinConstantsWithInsets:(UIEdgeInsets)insets;
|
||||
- (void)setTopPinConstant:(CGFloat)top left:(CGFloat)left bottom:(CGFloat)bottom right:(CGFloat)right;
|
||||
@ -47,4 +50,7 @@
|
||||
// For setting up the view.
|
||||
- (void)setupView;
|
||||
|
||||
// Add a view to be constrained in this view.
|
||||
- (void)addConstrainedView:(nonnull UIView *)view;
|
||||
|
||||
@end
|
||||
|
||||
@ -9,69 +9,50 @@
|
||||
#import "ViewConstrainingView.h"
|
||||
@import MVMCore.MVMCoreConstants;
|
||||
@import MVMCore.MVMCoreDispatchUtility;
|
||||
#import "NSLayoutConstraint+MFConvenience.h"
|
||||
#import "MFStyler.h"
|
||||
|
||||
@interface ViewConstrainingView ()
|
||||
@property (weak, nullable, nonatomic) UIView *constrainedView;
|
||||
@property (weak, nullable, nonatomic) UIView <MVMCoreUIMoleculeViewProtocol>*molecule;
|
||||
@end
|
||||
|
||||
@implementation ViewConstrainingView
|
||||
|
||||
- (nullable instancetype)initWithMolecule:(nonnull UIView <MVMCoreUIMoleculeViewProtocol>*)molecule alignment:(UIStackViewAlignment)alignment {
|
||||
if (self = [super init]) {
|
||||
if (!molecule.superview) {
|
||||
[self addConstrainedView:molecule alignment:alignment];
|
||||
[self setAsMolecule];
|
||||
}
|
||||
self.molecule = molecule;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
+ (nonnull ViewConstrainingView *)emptyView {
|
||||
ViewConstrainingView *view = [[ViewConstrainingView alloc] initWithFrame:CGRectZero];
|
||||
view.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
view.backgroundColor = [UIColor clearColor];
|
||||
return view;
|
||||
}
|
||||
|
||||
|
||||
+ (nonnull ViewConstrainingView *)viewConstrainingView:(UIView *)view {
|
||||
ViewConstrainingView *constrainingView = [[ViewConstrainingView alloc] initWithFrame:CGRectZero];
|
||||
constrainingView.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
constrainingView.backgroundColor = [UIColor clearColor];
|
||||
|
||||
view.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[constrainingView addSubview:view];
|
||||
constrainingView.constrainedView = view;
|
||||
|
||||
NSLayoutConstraint *leftPin = [view.leftAnchor constraintEqualToAnchor:constrainingView.leftAnchor];
|
||||
constrainingView.leftPin = leftPin;
|
||||
leftPin.active = YES;
|
||||
|
||||
NSLayoutConstraint *topPin = [view.topAnchor constraintEqualToAnchor:constrainingView.topAnchor];
|
||||
constrainingView.topPin = topPin;
|
||||
topPin.active = YES;
|
||||
|
||||
NSLayoutConstraint *bottomPin = [constrainingView.bottomAnchor constraintEqualToAnchor:view.bottomAnchor];
|
||||
constrainingView.bottomPin = bottomPin;
|
||||
bottomPin.active = YES;
|
||||
|
||||
NSLayoutConstraint *rightPin = [constrainingView.rightAnchor constraintEqualToAnchor:view.rightAnchor];
|
||||
constrainingView.rightPin = rightPin;
|
||||
rightPin.active = YES;
|
||||
|
||||
[constrainingView addConstrainedView:view];
|
||||
return constrainingView;
|
||||
}
|
||||
|
||||
- (void)pinToSuperView {
|
||||
|
||||
// Align left and right constants.
|
||||
NSLayoutConstraint *leftPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0];
|
||||
self.leftPin = leftPin;
|
||||
leftPin.active = YES;
|
||||
|
||||
NSLayoutConstraint *topPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self.superview attribute:NSLayoutAttributeTop multiplier:1.0 constant:0];
|
||||
self.topPin = topPin;
|
||||
topPin.active = YES;
|
||||
|
||||
NSLayoutConstraint *bottomPin = [NSLayoutConstraint constraintWithItem:self.superview attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0];
|
||||
self.bottomPin = bottomPin;
|
||||
bottomPin.active = YES;
|
||||
|
||||
NSLayoutConstraint *rightPin = [NSLayoutConstraint constraintWithItem:self.superview attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:0];
|
||||
self.rightPin = rightPin;
|
||||
rightPin.active = YES;
|
||||
NSDictionary *dictionary = [NSLayoutConstraint constraintPinSubviewToSuperview:self];
|
||||
self.leftPin = dictionary[ConstraintLeading];
|
||||
self.topPin = dictionary[ConstraintTop];
|
||||
self.bottomPin = dictionary[ConstraintBot];
|
||||
self.rightPin = dictionary[ConstraintTrailing];
|
||||
}
|
||||
|
||||
|
||||
- (void)setPinConstantsWithInsets:(UIEdgeInsets)insets {
|
||||
[self setTopPinConstant:insets.top left:insets.left bottom:insets.bottom right:insets.right];
|
||||
}
|
||||
@ -115,6 +96,34 @@
|
||||
self.backgroundColor = [UIColor clearColor];
|
||||
}
|
||||
|
||||
- (void)addConstrainedView:(nonnull UIView *)view alignment:(UIStackViewAlignment)alignment {
|
||||
view.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
[self addSubview:view];
|
||||
self.constrainedView = view;
|
||||
|
||||
NSLayoutRelation leftRelation;
|
||||
if (alignment == UIStackViewAlignmentFill || alignment == UIStackViewAlignmentLeading || alignment == UIStackViewAlignmentFirstBaseline) {
|
||||
leftRelation = NSLayoutRelationEqual;
|
||||
} else {
|
||||
leftRelation = NSLayoutRelationGreaterThanOrEqual;
|
||||
}
|
||||
NSLayoutRelation rightRelation;
|
||||
if (alignment == UIStackViewAlignmentFill || alignment == UIStackViewAlignmentTrailing || alignment == UIStackViewAlignmentLastBaseline) {
|
||||
rightRelation = NSLayoutRelationEqual;
|
||||
} else {
|
||||
rightRelation = NSLayoutRelationGreaterThanOrEqual;
|
||||
}
|
||||
NSDictionary *dictionary = [NSLayoutConstraint constraintPinSubview:view topRelation:NSLayoutRelationEqual bottomRelation:NSLayoutRelationEqual leftRelation:leftRelation rightRelation:rightRelation];
|
||||
self.leftPin = dictionary[ConstraintLeading];
|
||||
self.topPin = dictionary[ConstraintTop];
|
||||
self.bottomPin = dictionary[ConstraintBot];
|
||||
self.rightPin = dictionary[ConstraintTrailing];
|
||||
}
|
||||
|
||||
- (void)addConstrainedView:(nonnull UIView *)view {
|
||||
[self addConstrainedView:view alignment:UIStackViewAlignmentFill];
|
||||
}
|
||||
|
||||
- (void)setupView {
|
||||
[super setupView];
|
||||
self.translatesAutoresizingMaskIntoConstraints = NO;
|
||||
@ -131,6 +140,7 @@
|
||||
CGFloat padding = [MFStyler defaultHorizontalPaddingForSize:size];
|
||||
[self setLeftPinConstant:padding];
|
||||
[self setRightPinConstant:padding];
|
||||
[MFStyler setDefaultMarginsForView:self size:size];
|
||||
}];
|
||||
}
|
||||
}
|
||||
@ -141,4 +151,12 @@
|
||||
self.updateViewHorizontalDefaults = YES;
|
||||
}
|
||||
|
||||
- (void)setWithJSON:(NSDictionary *)json delegateObject:(DelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData {
|
||||
[super setWithJSON:json delegateObject:delegateObject additionalData:additionalData];
|
||||
if (self.molecule) {
|
||||
[self.molecule setWithJSON:json delegateObject:delegateObject additionalData:additionalData];
|
||||
self.backgroundColor = self.molecule.backgroundColor;
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -93,7 +93,7 @@ static NSTimeInterval const HandScrollAnimationTiming = 7.f;
|
||||
|
||||
BOOL automaticInset = NO;
|
||||
if (@available(iOS 11.0, *)) {
|
||||
automaticInset = self.scrollView.contentInsetAdjustmentBehavior == UIScrollViewContentInsetAdjustmentAutomatic;
|
||||
automaticInset = self.navigationController && self.scrollView.contentInsetAdjustmentBehavior == UIScrollViewContentInsetAdjustmentAutomatic;
|
||||
}
|
||||
|
||||
// Takes into account the navigation bar.
|
||||
|
||||
@ -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 {
|
||||
@ -304,6 +308,8 @@
|
||||
|| self.manager
|
||||
|| self.loadObject.requestParameters.tabWasPressed);
|
||||
}
|
||||
} else {
|
||||
[[MVMCoreUISession sharedGlobal].splitViewController.parentViewController setNeedsStatusBarAppearanceUpdate];
|
||||
}
|
||||
}
|
||||
|
||||
@ -339,7 +345,7 @@
|
||||
if (rightPanelLinkDict) {
|
||||
[[MVMCoreActionHandler sharedActionHandler] handleActionWithDictionary:rightPanelLinkDict
|
||||
additionalData:nil
|
||||
delegate:self];
|
||||
delegateObject:[self delegateObject]];
|
||||
return YES;
|
||||
} else {
|
||||
return NO;
|
||||
@ -494,6 +500,15 @@
|
||||
}
|
||||
}
|
||||
|
||||
//this method is needed for getting status bar style from present viewcotnroller
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle {
|
||||
if ([self respondsToSelector:@selector(defaultStatusBarStyle)]) {
|
||||
return [self defaultStatusBarStyle];
|
||||
} else {
|
||||
return UIStatusBarStyleDefault;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id<UIViewControllerTransitionCoordinator>)coordinator {
|
||||
|
||||
[super viewWillTransitionToSize:size withTransitionCoordinator:coordinator];
|
||||
@ -506,6 +521,10 @@
|
||||
} completion:completion];
|
||||
}
|
||||
|
||||
- (BOOL)viewRespectsSystemMinimumLayoutMargins {
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - UITextField Functions
|
||||
|
||||
// To Remove TextFields Bug: Keyboard is not dismissing after reaching textfield max length limit
|
||||
@ -603,7 +622,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 +677,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 +704,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) {
|
||||
|
||||
|
||||
255
MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift
Normal file
255
MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift
Normal file
@ -0,0 +1,255 @@
|
||||
//
|
||||
// ThreeLayerTableViewController.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/18/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MVMAnimationFramework
|
||||
|
||||
open class ThreeLayerTableViewController: MFProgrammaticTableViewController {
|
||||
// The three main views
|
||||
private var topView: UIView?
|
||||
private var bottomView: UIView?
|
||||
private var headerView: UIView?
|
||||
private var footerView: UIView?
|
||||
private var safeAreaView: UIView?
|
||||
var useMargins: Bool = true
|
||||
var bottomViewOutsideOfScrollArea: Bool = false
|
||||
private var topViewBottomConstraint: NSLayoutConstraint?
|
||||
private var bottomViewTopConstraint: NSLayoutConstraint?
|
||||
|
||||
//MARK: - MVMCoreViewProtocol
|
||||
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)
|
||||
showHeader()
|
||||
}
|
||||
if let bottomView = bottomView as? MVMCoreViewProtocol {
|
||||
bottomView.updateView(width)
|
||||
showFooter()
|
||||
}
|
||||
self.tableView?.reloadData()
|
||||
}
|
||||
|
||||
//MARK: - MFViewController
|
||||
open override func newDataBuildScreen() {
|
||||
super.newDataBuildScreen()
|
||||
createViewForTableHeader()
|
||||
createViewForTableFooter()
|
||||
tableView?.reloadData()
|
||||
}
|
||||
|
||||
override open func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
setToHaveNoSectionHeadersFooters()
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
//MARK: - Spacing
|
||||
// If both are subclassed to return a value, then the buttons will not be pinned towards the bottom because neither spacing would try to fill the screen.
|
||||
/// Space between the top view and the table sections, nil to fill. 0 default
|
||||
open func spaceBelowTopView() -> CGFloat? {
|
||||
return 0
|
||||
}
|
||||
|
||||
/// Space between the bottom view and the table sections, nil to fill. nil default
|
||||
open func spaceAboveBottomView() -> CGFloat? {
|
||||
return nil
|
||||
}
|
||||
|
||||
/// can override to return a minimum fill space.
|
||||
open func minimumFillSpace() -> CGFloat {
|
||||
return 0
|
||||
}
|
||||
|
||||
open override func updateViewConstraints() {
|
||||
super.updateViewConstraints()
|
||||
guard let tableView = tableView else {
|
||||
return
|
||||
}
|
||||
|
||||
let minimumSpace: CGFloat = minimumFillSpace()
|
||||
var currentSpace: CGFloat = 0
|
||||
var totalMinimumSpace: CGFloat = 0
|
||||
|
||||
var fillTop = false
|
||||
if spaceBelowTopView() == nil, self.tableView?.tableHeaderView != nil {
|
||||
fillTop = true
|
||||
currentSpace += topViewBottomConstraint?.constant ?? 0
|
||||
totalMinimumSpace += minimumSpace
|
||||
}
|
||||
|
||||
var fillBottom = false
|
||||
if spaceAboveBottomView() == nil, !bottomViewOutsideOfScrollArea, self.tableView?.tableFooterView != nil {
|
||||
fillBottom = true
|
||||
currentSpace += bottomViewTopConstraint?.constant ?? 0
|
||||
totalMinimumSpace += minimumSpace
|
||||
}
|
||||
|
||||
guard fillTop || fillBottom else {
|
||||
return
|
||||
}
|
||||
let newSpace = MVMCoreUIUtility.getVariableConstraintHeight(currentSpace, in: tableView, minimumHeight: totalMinimumSpace)
|
||||
|
||||
// If the bottom view is outside of the scroll, then only the top view constraint is being used, so we have to double it to account for the bottom constraint not being there when we compare to the new value.
|
||||
var currentSpaceForCompare: CGFloat = currentSpace
|
||||
if fillTop && bottomViewOutsideOfScrollArea {
|
||||
currentSpaceForCompare = currentSpace * 2;
|
||||
}
|
||||
|
||||
if !MVMCoreGetterUtility.cgfequalwiththreshold(newSpace, currentSpaceForCompare, 0.1) {
|
||||
if fillTop && fillBottom {
|
||||
// space both
|
||||
let half = newSpace / 2
|
||||
topViewBottomConstraint?.constant = half
|
||||
bottomViewTopConstraint?.constant = half
|
||||
showHeader()
|
||||
showFooter()
|
||||
} else if fillTop {
|
||||
// Only top is spaced (half the size if the bottom view is out of the scroll because it needs to be sized as if there are two spacers but there is only one.
|
||||
if bottomViewOutsideOfScrollArea {
|
||||
topViewBottomConstraint?.constant = newSpace / 2
|
||||
} else {
|
||||
topViewBottomConstraint?.constant = newSpace
|
||||
}
|
||||
showHeader()
|
||||
} else if fillBottom {
|
||||
// Only bottom is spaced.
|
||||
bottomViewTopConstraint?.constant = newSpace
|
||||
showFooter()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - Header Footer
|
||||
/// Gets the top view and adds it to a spacing view, headerView, and then calls showHeader.
|
||||
open func createViewForTableHeader() {
|
||||
let topView = viewForTop()
|
||||
self.topView = topView
|
||||
|
||||
let headerView = MVMCoreUICommonViewsUtility.commonView()
|
||||
headerView.addSubview(topView)
|
||||
topView.topAnchor.constraint(equalTo: headerView.topAnchor).isActive = true
|
||||
topView.leftAnchor.constraint(equalTo: headerView.leftAnchor).isActive = true
|
||||
headerView.rightAnchor.constraint(equalTo: topView.rightAnchor).isActive = true
|
||||
topViewBottomConstraint = headerView.bottomAnchor.constraint(equalTo: topView.bottomAnchor, constant: spaceBelowTopView() ?? 0)
|
||||
topViewBottomConstraint?.isActive = true
|
||||
self.headerView = headerView
|
||||
showHeader()
|
||||
}
|
||||
|
||||
/// Gets the bottom view and adds it to a spacing view, footerView, and then calls showFooter.
|
||||
open func createViewForTableFooter() {
|
||||
let bottomView = viewForBottom()
|
||||
self.bottomView = bottomView
|
||||
|
||||
let footerView = MVMCoreUICommonViewsUtility.commonView()
|
||||
footerView.addSubview(bottomView)
|
||||
bottomViewTopConstraint = bottomView.topAnchor.constraint(equalTo: footerView.topAnchor, constant: spaceAboveBottomView() ?? 0)
|
||||
bottomViewTopConstraint?.isActive = true
|
||||
bottomView.leftAnchor.constraint(equalTo: footerView.leftAnchor).isActive = true
|
||||
footerView.rightAnchor.constraint(equalTo: bottomView.rightAnchor).isActive = true
|
||||
footerView.bottomAnchor.constraint(equalTo: bottomView.bottomAnchor).isActive = true
|
||||
self.footerView = footerView
|
||||
showFooter()
|
||||
}
|
||||
|
||||
/// Takes the current headerView and adds it to the tableHeaderView
|
||||
func showHeader() {
|
||||
headerView?.removeFromSuperview()
|
||||
tableView?.tableHeaderView = nil
|
||||
guard let headerView = headerView else {
|
||||
return
|
||||
}
|
||||
|
||||
// This extra view is needed because of the wonkiness of apple's table header. Things breaks if using autolayout.
|
||||
MVMCoreUIUtility.sizeView(toFit: headerView)
|
||||
let tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: MVMCoreUIUtility.getWidth(), height: headerView.frame.height))
|
||||
tableHeaderView.addSubview(headerView)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: headerView)
|
||||
tableView?.tableHeaderView = tableHeaderView
|
||||
}
|
||||
|
||||
/// Takes the current footerView and adds it to the tableFooterView
|
||||
func showFooter() {
|
||||
footerView?.removeFromSuperview()
|
||||
safeAreaView?.removeFromSuperview()
|
||||
guard let footerView = footerView, let tableView = tableView else {
|
||||
return
|
||||
}
|
||||
|
||||
if bottomViewOutsideOfScrollArea {
|
||||
// put bottom view outside of scrolling area.
|
||||
bottomConstraint?.isActive = false
|
||||
view.addSubview(footerView)
|
||||
footerView.topAnchor.constraint(equalTo: tableView.bottomAnchor).isActive = true
|
||||
footerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
|
||||
view.rightAnchor.constraint(equalTo: footerView.rightAnchor).isActive = true
|
||||
if #available(iOS 11.0, *) {
|
||||
view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: footerView.bottomAnchor).isActive = true
|
||||
safeAreaView = MVMCoreUICommonViewsUtility.getAndSetupSafeAreaView(on: view)
|
||||
safeAreaView?.backgroundColor = bottomView?.backgroundColor
|
||||
} else {
|
||||
view.bottomAnchor.constraint(equalTo: footerView.bottomAnchor).isActive = true
|
||||
}
|
||||
} else {
|
||||
bottomConstraint?.isActive = true
|
||||
var y: CGFloat?
|
||||
if let tableFooterView = tableView.tableFooterView {
|
||||
// if footer already exists, use the same y location to avoid strange moving animation
|
||||
y = tableFooterView.frame.minY
|
||||
}
|
||||
|
||||
// This extra view is needed because of the wonkiness of apple's table footer. Things breaks if using autolayout.
|
||||
MVMCoreUIUtility.sizeView(toFit: footerView)
|
||||
let tableFooterView = UIView(frame: CGRect(x: 0, y: y ?? 0, width: MVMCoreUIUtility.getWidth(), height: footerView.frame.height))
|
||||
tableFooterView.addSubview(footerView)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: footerView)
|
||||
tableView.tableFooterView = tableFooterView
|
||||
}
|
||||
}
|
||||
|
||||
//MARK: - Functions to subclass
|
||||
/// Subclass for a top view.
|
||||
open func viewForTop() -> UIView {
|
||||
let view = MVMCoreUICommonViewsUtility.commonView()
|
||||
view.heightAnchor.constraint(equalToConstant: 0).isActive = true
|
||||
return view
|
||||
}
|
||||
|
||||
/// Subclass for a bottom view.
|
||||
open func viewForBottom() -> UIView {
|
||||
let view = MVMCoreUICommonViewsUtility.commonView()
|
||||
view.heightAnchor.constraint(equalToConstant: 0).isActive = true
|
||||
return view
|
||||
}
|
||||
|
||||
//MARK: - Scrollview
|
||||
open override func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
// To stop handscroll animation if animating after scroll
|
||||
stopHandScrollAnimation(true)
|
||||
}
|
||||
|
||||
deinit {
|
||||
tableView?.delegate = nil
|
||||
}
|
||||
|
||||
//MARK: - Animation
|
||||
open override func setupIntroAnimations() {
|
||||
if let topView = topView, topView.subviews.count > 0 {
|
||||
introAnimationManager?.addAnimation(animation: MVMAnimations.fadeUpAnimation(view: topView))
|
||||
}
|
||||
if let tableView = tableView {
|
||||
introAnimationManager?.addAnimation(animation: MVMAnimations.animateTableViewFadeInCells(tableView: tableView))
|
||||
}
|
||||
if let bottomView = bottomView, bottomView.subviews.count > 0 {
|
||||
introAnimationManager?.addAnimation(animation: MVMAnimations.fadeUpAnimation(view: bottomView))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,6 +16,7 @@ open class ThreeLayerViewController: ProgrammaticScrollViewController {
|
||||
var topView: UIView?
|
||||
var middleView: UIView?
|
||||
var bottomView: UIView?
|
||||
var useMargins: Bool = false
|
||||
|
||||
// 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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -31,8 +31,12 @@ extern NSString * _Nonnull const ConstraintWidth;
|
||||
|
||||
+ (nullable NSDictionary *)constraintPinSubview:(nullable UIView *)subview pinTop:(BOOL)pinTop pinBottom:(BOOL)pinBottom pinLeft:(BOOL)pinLeft pinRight:(BOOL)pinRight;
|
||||
|
||||
+ (nullable NSDictionary *)constraintPinSubview:(nullable UIView *)subview topRelation:(NSLayoutRelation)topRelation bottomRelation:(NSLayoutRelation)bottomRelation leftRelation:(NSLayoutRelation)leftRelation rightRelation:(NSLayoutRelation)rightRelation;
|
||||
|
||||
+ (nullable NSDictionary *)constraintPinSubview:(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;
|
||||
|
||||
+ (nullable NSDictionary *)constraintPinSubview:(nullable UIView *)subview pinTop:(BOOL)pinTop topConstant:(CGFloat)topConstant topRelation:(NSLayoutRelation)topRelation pinBottom:(BOOL)pinBottom bottomConstant:(CGFloat)bottomConstant bottomRelation:(NSLayoutRelation)bottomRelation pinLeft:(BOOL)pinLeft leftConstant:(CGFloat)leftConstant leftRelation:(NSLayoutRelation)leftRelation pinRight:(BOOL)pinRight rightConstant:(CGFloat)rightConstant rightRelation:(NSLayoutRelation)rightRelation;
|
||||
|
||||
// Pin subview with 1 side
|
||||
+ (nullable NSDictionary *)constraintPinTopSubview:(nonnull UIView *)subview topConstant:(CGFloat)topConstant;
|
||||
+ (nullable NSDictionary *)constraintPinBottomSubview:(nonnull UIView *)subview bottomConstant:(CGFloat)bottomConstant;
|
||||
@ -55,6 +59,14 @@ 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 NSDictionary <NSString *, NSLayoutConstraint *>*)pinViewToSuperview:(nonnull UIView *)subview useMargins:(BOOL)useMargins;
|
||||
+ (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).
|
||||
|
||||
@ -44,29 +44,37 @@ NSString *const ConstraintWidth = @"width";
|
||||
return [NSLayoutConstraint constraintPinSubview:subview pinTop:pinTop topConstant:0 pinBottom:pinBottom bottomConstant:0 pinLeft:pinLeft leftConstant:0 pinRight:pinRight rightConstant:0];
|
||||
}
|
||||
|
||||
+ (nullable NSDictionary *)constraintPinSubview:(nullable UIView *)subview topRelation:(NSLayoutRelation)topRelation bottomRelation:(NSLayoutRelation)bottomRelation leftRelation:(NSLayoutRelation)leftRelation rightRelation:(NSLayoutRelation)rightRelation {
|
||||
return [self constraintPinSubview:subview pinTop:YES topConstant:0 topRelation:topRelation pinBottom:YES bottomConstant:0 bottomRelation:bottomRelation pinLeft:YES leftConstant:0 leftRelation:leftRelation pinRight:YES rightConstant:0 rightRelation:rightRelation];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)constraintPinSubview:(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 {
|
||||
return [self constraintPinSubview:subview pinTop:pinTop topConstant:topConstant topRelation:NSLayoutRelationEqual pinBottom:pinBottom bottomConstant:bottomConstant bottomRelation:NSLayoutRelationEqual pinLeft:pinLeft leftConstant:leftConstant leftRelation:NSLayoutRelationEqual pinRight:pinRight rightConstant:rightConstant rightRelation:NSLayoutRelationEqual];
|
||||
}
|
||||
|
||||
+ (NSDictionary *)constraintPinSubview:(UIView *)subview pinTop:(BOOL)pinTop topConstant:(CGFloat)topConstant topRelation:(NSLayoutRelation)topRelation pinBottom:(BOOL)pinBottom bottomConstant:(CGFloat)bottomConstant bottomRelation:(NSLayoutRelation)bottomRelation pinLeft:(BOOL)pinLeft leftConstant:(CGFloat)leftConstant leftRelation:(NSLayoutRelation)leftRelation pinRight:(BOOL)pinRight rightConstant:(CGFloat)rightConstant rightRelation:(NSLayoutRelation)rightRelation {
|
||||
UIView *superview = subview.superview;
|
||||
NSMutableDictionary *constraintDic = [[NSMutableDictionary alloc] init];
|
||||
if (pinTop) {
|
||||
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeTop multiplier:1 constant:topConstant];
|
||||
NSLayoutConstraint *top = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeTop relatedBy:topRelation toItem:superview attribute:NSLayoutAttributeTop multiplier:1 constant:topConstant];
|
||||
top.priority = 999;
|
||||
top.active = YES;
|
||||
[constraintDic setObject:top forKey:ConstraintTop];
|
||||
}
|
||||
if (pinBottom) {
|
||||
NSLayoutConstraint *bottom = [NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:subview attribute:NSLayoutAttributeBottom multiplier:1 constant:bottomConstant];
|
||||
NSLayoutConstraint *bottom = [NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeBottom relatedBy:bottomRelation toItem:subview attribute:NSLayoutAttributeBottom multiplier:1 constant:bottomConstant];
|
||||
bottom.priority = 999;
|
||||
bottom.active = YES;
|
||||
[constraintDic setObject:bottom forKey:ConstraintBot];
|
||||
}
|
||||
if (pinLeft) {
|
||||
NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:superview attribute:NSLayoutAttributeLeading multiplier:1 constant:leftConstant];
|
||||
NSLayoutConstraint *leading = [NSLayoutConstraint constraintWithItem:subview attribute:NSLayoutAttributeLeading relatedBy:leftRelation toItem:superview attribute:NSLayoutAttributeLeading multiplier:1 constant:leftConstant];
|
||||
leading.priority = 999;
|
||||
leading.active = YES;
|
||||
[constraintDic setObject:leading forKey:ConstraintLeading];
|
||||
}
|
||||
if (pinRight) {
|
||||
NSLayoutConstraint *trailing = [NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeTrailing relatedBy:NSLayoutRelationEqual toItem:subview attribute:NSLayoutAttributeTrailing multiplier:1 constant:rightConstant];
|
||||
NSLayoutConstraint *trailing = [NSLayoutConstraint constraintWithItem:superview attribute:NSLayoutAttributeTrailing relatedBy:rightRelation toItem:subview attribute:NSLayoutAttributeTrailing multiplier:1 constant:rightConstant];
|
||||
trailing.priority = 999;
|
||||
trailing.active = YES;
|
||||
[constraintDic setObject:trailing forKey:ConstraintTrailing];
|
||||
@ -150,6 +158,32 @@ NSString *const ConstraintWidth = @"width";
|
||||
return constraintsDictionary;
|
||||
}
|
||||
|
||||
#pragma mark - With Margins
|
||||
|
||||
+ (nonnull NSDictionary *)pinViewToSuperview:(nonnull UIView *)subview useMargins:(BOOL)useMargins {
|
||||
return @{ConstraintTop:[self pinViewTopToSuperview:subview useMargins:useMargins constant:0],
|
||||
ConstraintLeading:[self pinViewLeftToSuperview:subview useMargins:useMargins constant:0],
|
||||
ConstraintTrailing:[self pinViewRightToSuperview:subview useMargins:useMargins constant:0],
|
||||
ConstraintBot:[self pinViewBottomToSuperview:subview useMargins:useMargins constant:0],
|
||||
};
|
||||
}
|
||||
|
||||
+ (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 {
|
||||
|
||||
@ -30,6 +30,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
// View Controller can override this method and do custom action instead of opening the left panel
|
||||
- (BOOL)isOverridingLeftButton;
|
||||
|
||||
//return desired status bar style based on different View Controller
|
||||
- (UIStatusBarStyle)defaultStatusBarStyle;
|
||||
- (nullable UIColor *)defaultStatusBarBackgroundColor;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
||||
@ -105,6 +105,10 @@ typedef NS_ENUM(NSInteger, MFNumberOfDrawers) {
|
||||
+ (CGFloat)getApplicationViewWidth;
|
||||
+ (CGFloat)getApplicationViewMaxSize;
|
||||
|
||||
// return subviewcontrollers' prefer status bar style
|
||||
- (UIStatusBarStyle)getDefaultStatusBarStyle;
|
||||
- (nullable UIColor *)getDefaultStatusBarBackgroundColor;
|
||||
|
||||
#pragma mark - Main Subclassables
|
||||
|
||||
// Can subclass to set threshold for when the drawers are permanently extended. Default is 1000 for the left panel and 2000 for both.
|
||||
|
||||
@ -877,7 +877,33 @@ CGFloat const PanelAnimationDuration = 0.2;
|
||||
}
|
||||
|
||||
- (UIStatusBarStyle)preferredStatusBarStyle {
|
||||
return self.topAlertView.statusBarStyle;
|
||||
if (self.topAlertView.topAlertObject) {
|
||||
return self.topAlertView.statusBarStyle;
|
||||
} else {
|
||||
UIStatusBarStyle style = [self getDefaultStatusBarStyle];
|
||||
[self.topAlertView resetDefaultBackgroundColor:[self getDefaultStatusBarBackgroundColor] basedOnStatusBarStyle:style];
|
||||
return style;
|
||||
}
|
||||
}
|
||||
|
||||
- (UIStatusBarStyle)getDefaultStatusBarStyle {
|
||||
UIViewController *viewController = [self getCurrentDetailViewController];
|
||||
if ([viewController conformsToProtocol:@protocol(MVMCoreUIDetailViewProtocol)]
|
||||
&& [viewController respondsToSelector:@selector(defaultStatusBarStyle)]
|
||||
&& [((UIViewController <MVMCoreUIDetailViewProtocol> *)viewController) defaultStatusBarStyle]) {
|
||||
return [((UIViewController <MVMCoreUIDetailViewProtocol> *)viewController) defaultStatusBarStyle];
|
||||
}
|
||||
return UIStatusBarStyleDefault;
|
||||
}
|
||||
|
||||
- (UIColor *)getDefaultStatusBarBackgroundColor {
|
||||
UIViewController *viewController = [self getCurrentDetailViewController];
|
||||
if ([viewController conformsToProtocol:@protocol(MVMCoreUIDetailViewProtocol)]
|
||||
&& [viewController respondsToSelector:@selector(defaultStatusBarBackgroundColor)]
|
||||
&& [((UIViewController <MVMCoreUIDetailViewProtocol> *)viewController) defaultStatusBarBackgroundColor]) {
|
||||
return [((UIViewController <MVMCoreUIDetailViewProtocol> *)viewController) defaultStatusBarBackgroundColor];
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
#pragma mark - Getters
|
||||
|
||||
@ -25,6 +25,9 @@
|
||||
// true while panning
|
||||
@property (nonatomic) BOOL panning;
|
||||
|
||||
//set pannable percentage 0 to 1
|
||||
@property (nonatomic) CGFloat pannablePercentage;
|
||||
|
||||
// can be used to keep track of if we are ..
|
||||
@property (nonatomic) BOOL interactive;
|
||||
|
||||
|
||||
@ -8,8 +8,6 @@
|
||||
|
||||
#import "MFTabBarInteractor.h"
|
||||
|
||||
static CGFloat pannablePercentage = 0.15;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, MFTabBarPanningDirection) {
|
||||
MFTabBarPanningDirectionLeft,
|
||||
MFTabBarPanningDirectionRight
|
||||
@ -33,6 +31,7 @@ typedef NS_ENUM(NSUInteger, MFTabBarPanningDirection) {
|
||||
|
||||
- (nullable instancetype)initWithViewController:(nullable UIViewController *)viewController delegate:(nullable id<MFSwipeNavigationProtocol>)delegate {
|
||||
if (self = [super init]) {
|
||||
self.pannablePercentage = 0.15;
|
||||
self.panGesture = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handlePanGesture:)];
|
||||
[viewController.view addGestureRecognizer:self.panGesture];
|
||||
self.delegate = delegate;
|
||||
@ -48,8 +47,8 @@ typedef NS_ENUM(NSUInteger, MFTabBarPanningDirection) {
|
||||
|
||||
// Simulates an edge gesture by only accepting pans at the edge of the screen. Needed because edge gesture doesn't work nicely with extended menus such as on ipad.
|
||||
CGRect frame = pan.view.frame;
|
||||
CGRect pannableFrameLeft = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width*pannablePercentage, frame.size.height);
|
||||
CGRect pannableFrameRight = CGRectMake(frame.origin.x + frame.size.width*(1-pannablePercentage), frame.origin.y, frame.size.width*pannablePercentage, frame.size.height);
|
||||
CGRect pannableFrameLeft = CGRectMake(frame.origin.x, frame.origin.y, frame.size.width*self.pannablePercentage, frame.size.height);
|
||||
CGRect pannableFrameRight = CGRectMake(frame.origin.x + frame.size.width*(1-self.pannablePercentage), frame.origin.y, frame.size.width*self.pannablePercentage, frame.size.height);
|
||||
|
||||
switch (pan.state) {
|
||||
case UIGestureRecognizerStateBegan:
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -193,13 +193,7 @@ static NSString * const COLLECTION_CELL_ID = @"cell";
|
||||
[label layoutIfNeeded];
|
||||
label.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
|
||||
|
||||
//set up cell acceessibility label
|
||||
cell.isAccessibilityElement = NO;
|
||||
cell.contentView.isAccessibilityElement = YES;
|
||||
|
||||
NSString *accLabel = [title stringByAppendingString:[MVMCoreUIUtility hardcodedStringWithKey:@"AccTab"]];
|
||||
cell.contentView.accessibilityLabel = accLabel;
|
||||
[cell.contentView setAccessibilityHint:[MVMCoreUIUtility hardcodedStringWithKey:@"AccTabHint"]];
|
||||
[self setCellAccessibility:cell title:label.text isSelected:NO indexPath:indexPath];
|
||||
|
||||
if (indexPath.row == self.selectedIndex) {
|
||||
label.textColor = [UIColor mfTomatoRed];
|
||||
@ -404,20 +398,27 @@ static NSString * const COLLECTION_CELL_ID = @"cell";
|
||||
[cell layoutIfNeeded];
|
||||
}
|
||||
|
||||
//setup selected tab accessibility
|
||||
NSString *string = label.text;
|
||||
NSString *accLabel = [string stringByAppendingString:[MVMCoreUIUtility hardcodedStringWithKey:@"toptabbar_tab_selected"]];
|
||||
cell.contentView.accessibilityLabel = accLabel;
|
||||
[cell.contentView setAccessibilityHint:nil];
|
||||
|
||||
self.selectedIndex = indexPath.row;
|
||||
if ([self.delegate respondsToSelector:@selector(topTabbar:titleForItemAtIndex:)]){
|
||||
[self.delegate topTabbar:self didSelectItemAtIndex:indexPath.row];
|
||||
}
|
||||
|
||||
[self setCellAccessibility:cell title:label.text isSelected:YES indexPath:indexPath];
|
||||
}
|
||||
|
||||
- (void)reloadData {
|
||||
[self.collectionView reloadData];
|
||||
}
|
||||
|
||||
- (void)setCellAccessibility:(UICollectionViewCell *)cell title:(NSString *)title isSelected:(BOOL)isSelected indexPath:(NSIndexPath *)indexPath {
|
||||
cell.isAccessibilityElement = NO;
|
||||
cell.contentView.isAccessibilityElement = YES;
|
||||
NSString *accKey = isSelected ? @"toptabbar_tab_selected" : @"AccTab";
|
||||
NSString *accLabel = [title stringByAppendingString:[MVMCoreUIUtility hardcodedStringWithKey:accKey]];
|
||||
NSString *accString = [accLabel stringByAppendingString:[NSString stringWithFormat:[MVMCoreUIUtility hardcodedStringWithKey:@"AccTabIndex"], indexPath.row + 1, [self.datasource numberOfTopTabbarItems:self]]];
|
||||
cell.contentView.accessibilityLabel = accString;
|
||||
NSString *accHint = isSelected ? nil : [MVMCoreUIUtility hardcodedStringWithKey:@"AccTabHint"];
|
||||
[cell.contentView setAccessibilityHint:accHint];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -22,6 +22,6 @@ import Foundation
|
||||
// The Field name key value pair for sending to server
|
||||
@objc optional func formFieldName() -> String?
|
||||
|
||||
// The Feild value key value paid for sending to server
|
||||
@objc optional func formFieldValue() -> String?
|
||||
// The Field value key value pair for sending to server
|
||||
@objc optional func formFieldValue() -> Any?
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
|
||||
@ -10,7 +10,6 @@
|
||||
#import <MVMCoreUI/StackableViewController.h>
|
||||
#import <MVMCoreUI/ViewConstrainingView.h>
|
||||
#import <MVMCoreUI/TopLabelsView.h>
|
||||
|
||||
@class LabelView;
|
||||
@class PrimaryButton;
|
||||
|
||||
@ -24,6 +23,7 @@
|
||||
@property (nullable, weak, nonatomic) UIView *viewInScroll;
|
||||
@property (nullable, weak, nonatomic) UIView *viewOutOfScroll;
|
||||
@property (nullable, strong, nonatomic) UIView *safeAreaView;
|
||||
@property (nullable, weak, nonatomic) ViewConstrainingView *bottomAccessoryView;
|
||||
|
||||
// Set to overwrite which view is the top edge and/or bottom edge of the between view. must be added to the ui and constrained before buildViewsBetweenLabelsAndButtons.
|
||||
// Use these to create views that are pinned near the labels or buttons and are separate from any centered content. Add and set in buildInAdditionalViewsBeforeCenteredContent.
|
||||
|
||||
@ -30,7 +30,6 @@
|
||||
@property (nullable, weak, nonatomic) NSArray *middleViews;
|
||||
|
||||
@property (nullable, weak, nonatomic) UIView *betweenView;
|
||||
@property (nullable, weak, nonatomic) ViewConstrainingView *bottomAccessoryView;
|
||||
|
||||
// Adds the button view to the screen. Out of the scroll or in.
|
||||
- (void)addViewOutsideOfScrollView:(UIView *)bottomView;
|
||||
@ -127,7 +126,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;
|
||||
|
||||
@ -72,8 +72,6 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[];
|
||||
|
||||
#pragma mark - Atoms
|
||||
#pragma mark Views
|
||||
#import <MVMCoreUI/MFView.h>
|
||||
#import <MVMCoreUI/MFLabel.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
|
||||
@ -110,6 +110,14 @@ import UIKit
|
||||
rightPin?.isActive = true
|
||||
}
|
||||
|
||||
open func alignFill() {
|
||||
alignCenterPin?.isActive = false
|
||||
alignCenterLeftPin?.isActive = false
|
||||
alignCenterRightPin?.isActive = false
|
||||
leftPin?.isActive = true
|
||||
rightPin?.isActive = true
|
||||
}
|
||||
|
||||
open override func setLeftPinConstant(_ constant: CGFloat) {
|
||||
super.setLeftPinConstant(constant)
|
||||
alignCenterLeftPin?.constant = constant
|
||||
|
||||
@ -7,17 +7,27 @@
|
||||
//
|
||||
|
||||
#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
|
||||
|
||||
// Called after init to provide an early setter for any molecule specific logic
|
||||
- (void)setAsMolecule;
|
||||
|
||||
// Notifies the creator that the view needs to be constrained in a view.
|
||||
- (BOOL)needsToBeConstrained;
|
||||
|
||||
// The alignment for the molecule if constrained.
|
||||
- (UIStackViewAlignment)moleculeAlignment;
|
||||
|
||||
// For the molecule list to load more efficiently.
|
||||
+ (CGFloat)estimatedHeightForRow;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@ -11,18 +11,20 @@ import UIKit
|
||||
public class MoleculeStackView: MFView {
|
||||
var spacingBlock: ((Any) -> UIEdgeInsets)?
|
||||
var moleculesArray: [UIView]?
|
||||
|
||||
var useMargins: Bool = false
|
||||
|
||||
// MARK: - Inits
|
||||
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
|
||||
}
|
||||
|
||||
@ -30,6 +32,7 @@ public class MoleculeStackView: MFView {
|
||||
fatalError("init(coder:) has not been implemented")
|
||||
}
|
||||
|
||||
// MARK: - MFViewProtocol
|
||||
public override func setupView() {
|
||||
super.setupView()
|
||||
translatesAutoresizingMaskIntoConstraints = false
|
||||
@ -47,17 +50,17 @@ public class MoleculeStackView: MFView {
|
||||
}
|
||||
}
|
||||
|
||||
public override func setWithJSON(_ json: [AnyHashable : Any]?, delegate: NSObject?, additionalData: [AnyHashable : Any]?) {
|
||||
super.setWithJSON(json, delegate: delegate, additionalData: additionalData)
|
||||
guard let molecules = json?.arrayForKey("molecules") as? [[String: Any]] else {
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
guard let molecules = json?.arrayForKey(KeyMolecules) as? [[String: Any]] else {
|
||||
return
|
||||
}
|
||||
|
||||
// Create the molecules and set the json.
|
||||
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)
|
||||
if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject) {
|
||||
moleculesArray.append(molecule)
|
||||
}
|
||||
}
|
||||
@ -67,14 +70,11 @@ 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
|
||||
if object as AnyObject? === moleculesArray.first {
|
||||
return UIEdgeInsets.zero
|
||||
} else {
|
||||
return UIEdgeInsets.init(top: PaddingTwo, left: 0, bottom: 0, right: 0)
|
||||
}
|
||||
let separation = json?.optionalCGFloatForKey("separation") ?? PaddingDefault
|
||||
MVMCoreUIStackableViewController.populateView(self, withUIArray: moleculesArray, useMargins: useMargins) { (object) -> UIEdgeInsets in
|
||||
return UIEdgeInsets.init(top: separation, left: 0, bottom: 0, right: 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
152
MVMCoreUI/Molecules/MoleculeTableViewCell.swift
Normal file
152
MVMCoreUI/Molecules/MoleculeTableViewCell.swift
Normal file
@ -0,0 +1,152 @@
|
||||
//
|
||||
// MoleculeTableViewCell.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/18/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@objcMembers open class MoleculeTableViewCell: UITableViewCell, MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol {
|
||||
open var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)?
|
||||
|
||||
// For the accessory view convenience.
|
||||
public var caretView: CaretView?
|
||||
private var caretViewWidthSizeObject: MFSizeObject?
|
||||
private var caretViewHeightSizeObject: MFSizeObject?
|
||||
|
||||
// For separation between cells.
|
||||
public var topSeparatorView: SeparatorView?
|
||||
public var bottomSeparatorView: SeparatorView?
|
||||
public enum SeparatorFrequency: String {
|
||||
case All = "all"
|
||||
case AllExceptTop = "allExceptTop"
|
||||
case AllExceptBottom = "allExceptBottom"
|
||||
case Between = "between"
|
||||
}
|
||||
|
||||
// MARK: - Inits
|
||||
public override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
|
||||
super.init(style: style, reuseIdentifier: reuseIdentifier)
|
||||
setupView()
|
||||
}
|
||||
|
||||
public required init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
setupView()
|
||||
}
|
||||
|
||||
// MARK: - MFViewProtocol
|
||||
public func updateView(_ size: CGFloat) {
|
||||
MFStyler.setDefaultMarginsFor(self, size: size)
|
||||
if #available(iOS 11.0, *) {
|
||||
contentView.directionalLayoutMargins = directionalLayoutMargins
|
||||
topSeparatorView?.setLeftAndRightPinConstant(directionalLayoutMargins.leading)
|
||||
bottomSeparatorView?.setLeftAndRightPinConstant(directionalLayoutMargins.leading)
|
||||
} else {
|
||||
contentView.layoutMargins = layoutMargins
|
||||
topSeparatorView?.setLeftAndRightPinConstant(layoutMargins.left)
|
||||
bottomSeparatorView?.setLeftAndRightPinConstant(layoutMargins.left)
|
||||
}
|
||||
|
||||
if let molecule = molecule as? MVMCoreViewProtocol {
|
||||
molecule.updateView(size)
|
||||
}
|
||||
if let _ = accessoryView, let caretView = caretView, let widthObject = caretViewWidthSizeObject, let heightObject = caretViewHeightSizeObject {
|
||||
caretView.frame = CGRect(x: 0, y: 0, width: widthObject.getValueBased(onSize: size), height: heightObject.getValueBased(onSize: size))
|
||||
}
|
||||
topSeparatorView?.updateView(size)
|
||||
bottomSeparatorView?.updateView(size)
|
||||
}
|
||||
|
||||
public func setupView() {
|
||||
preservesSuperviewLayoutMargins = false
|
||||
contentView.preservesSuperviewLayoutMargins = false
|
||||
selectionStyle = .none
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
guard let json = json else {
|
||||
return
|
||||
}
|
||||
if molecule == nil {
|
||||
if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: json, delegateObject: delegateObject) {
|
||||
contentView.addSubview(moleculeView)
|
||||
NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: moleculeView.needsToBeConstrained?() ?? false).values))
|
||||
molecule = moleculeView
|
||||
}
|
||||
} else {
|
||||
molecule?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
backgroundColor = molecule?.backgroundColor
|
||||
}
|
||||
|
||||
// MARK: - Convenience
|
||||
/// Adds the standard mvm style caret to the accessory view
|
||||
public func addCaretViewAccessory() {
|
||||
guard accessoryView == nil else {
|
||||
return
|
||||
}
|
||||
let width: CGFloat = 6
|
||||
let height: CGFloat = 10
|
||||
caretView = CaretView(lineThickness: CaretView.thin)
|
||||
caretView?.frame = CGRect(x: 0, y: 0, width: width, height: height)
|
||||
caretViewWidthSizeObject = MFSizeObject(scalingStandardSize: width)
|
||||
caretViewHeightSizeObject = MFSizeObject(scalingStandardSize: height)
|
||||
accessoryView = caretView
|
||||
}
|
||||
|
||||
func addSeparatorsIfNeeded() {
|
||||
if topSeparatorView == nil {
|
||||
topSeparatorView = SeparatorView.separatorAdd(to: self, position: SeparatorPositionTop)
|
||||
topSeparatorView?.hide()
|
||||
}
|
||||
if bottomSeparatorView == nil {
|
||||
bottomSeparatorView = SeparatorView.separatorAdd(to: self, position: SeparatorPositionBot)
|
||||
bottomSeparatorView?.hide()
|
||||
}
|
||||
}
|
||||
|
||||
/// For when the separator between cells shows using json and frequency.
|
||||
public func setSeparatorWithJSON(_ json: [AnyHashable : Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?, indexPath: IndexPath) {
|
||||
guard let json = json else {
|
||||
return
|
||||
}
|
||||
addSeparatorsIfNeeded()
|
||||
topSeparatorView?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
bottomSeparatorView?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
if let separatorFrequencyString = json.optionalStringForKey("frequency"), let separatorFrequency = SeparatorFrequency(rawValue: separatorFrequencyString) {
|
||||
setSeparatorFrequency(separatorFrequency, indexPath: indexPath)
|
||||
}
|
||||
}
|
||||
|
||||
/// For when the separator between cells shows.
|
||||
public func setSeparatorFrequency(_ separatorFrequency: SeparatorFrequency, indexPath: IndexPath) {
|
||||
switch separatorFrequency {
|
||||
case .All:
|
||||
if indexPath.row == 0 {
|
||||
topSeparatorView?.show()
|
||||
} else {
|
||||
topSeparatorView?.hide()
|
||||
}
|
||||
bottomSeparatorView?.show()
|
||||
case .AllExceptBottom:
|
||||
topSeparatorView?.show()
|
||||
bottomSeparatorView?.hide()
|
||||
case .Between:
|
||||
if indexPath.row == 0 {
|
||||
topSeparatorView?.hide()
|
||||
} else {
|
||||
topSeparatorView?.show()
|
||||
}
|
||||
bottomSeparatorView?.hide()
|
||||
case .AllExceptTop:
|
||||
fallthrough
|
||||
default:
|
||||
topSeparatorView?.hide()
|
||||
bottomSeparatorView?.show()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -46,16 +46,16 @@ public class StandardFooterView: ViewConstrainingView {
|
||||
spaceBetweenButtons = textButton.topAnchor.constraint(equalTo: twoButtonView.bottomAnchor, constant: PaddingTwo)
|
||||
spaceBetweenButtons?.isActive = true
|
||||
|
||||
leftConstraintTwoButton = twoButtonView.leftAnchor.constraint(equalTo: leftAnchor)
|
||||
leftConstraintTwoButton = twoButtonView.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor)
|
||||
leftConstraintTwoButton?.isActive = true
|
||||
|
||||
rightConstraintTwoButton = rightAnchor.constraint(equalTo: twoButtonView.rightAnchor)
|
||||
rightConstraintTwoButton = layoutMarginsGuide.rightAnchor.constraint(equalTo: twoButtonView.rightAnchor)
|
||||
rightConstraintTwoButton?.isActive = true
|
||||
|
||||
leftConstraintTextButton = textButton.leftAnchor.constraint(greaterThanOrEqualTo: leftAnchor)
|
||||
leftConstraintTextButton = textButton.leftAnchor.constraint(greaterThanOrEqualTo: layoutMarginsGuide.leftAnchor)
|
||||
leftConstraintTextButton?.isActive = true
|
||||
|
||||
rightConstraintTextButton = rightAnchor.constraint(greaterThanOrEqualTo: textButton.rightAnchor)
|
||||
rightConstraintTextButton = layoutMarginsGuide.rightAnchor.constraint(greaterThanOrEqualTo: textButton.rightAnchor)
|
||||
rightConstraintTextButton?.isActive = true
|
||||
|
||||
centerAlignTextButton = textButton.centerXAnchor.constraint(equalTo: centerXAnchor)
|
||||
@ -93,22 +93,12 @@ public class StandardFooterView: ViewConstrainingView {
|
||||
layoutIfNeeded()
|
||||
}
|
||||
|
||||
public override func setLeftPinConstant(_ constant: CGFloat) {
|
||||
leftConstraintTwoButton?.constant = constant
|
||||
leftConstraintTextButton?.constant = constant
|
||||
}
|
||||
|
||||
public override func setRightPinConstant(_ constant: CGFloat) {
|
||||
rightConstraintTwoButton?.constant = constant
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -9,8 +9,8 @@
|
||||
import UIKit
|
||||
|
||||
public class StandardHeaderView: ViewConstrainingView {
|
||||
let headlineLabel = MFLabel.commonLabelH2(true)
|
||||
let messageLabel = MFLabel.commonLabelB2(true)
|
||||
let headlineLabel = Label.commonLabelH2(true)
|
||||
let messageLabel = Label.commonLabelB2(true)
|
||||
var separatorView: SeparatorView?
|
||||
var spaceBetweenLabels: NSLayoutConstraint?
|
||||
var leftConstraintTitle: NSLayoutConstraint?
|
||||
@ -75,10 +75,10 @@ public class StandardHeaderView: ViewConstrainingView {
|
||||
}
|
||||
|
||||
public func setSpacing() {
|
||||
if headlineLabel.hasText() && messageLabel.hasText() {
|
||||
if headlineLabel.hasText && messageLabel.hasText {
|
||||
spaceBetweenLabels?.constant = PaddingTwo
|
||||
show()
|
||||
} else if headlineLabel.hasText() || messageLabel.hasText() {
|
||||
} else if headlineLabel.hasText || messageLabel.hasText {
|
||||
spaceBetweenLabels?.constant = 0
|
||||
show()
|
||||
} else {
|
||||
@ -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
|
||||
|
||||
@ -7,17 +7,16 @@
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <MVMCoreUI/MFView.h>
|
||||
#import <MVMCoreUI/MFLabel.h>
|
||||
@class Label;
|
||||
#import <MVMCoreUI/SeparatorView.h>
|
||||
|
||||
@class TopLabelsAndBottomButtonsTableViewController;
|
||||
|
||||
@interface TopLabelsView : MFView
|
||||
|
||||
@property (nullable, weak, nonatomic) MFLabel *headlineLabel;
|
||||
@property (nullable, weak, nonatomic) MFLabel *messageLabel;
|
||||
@property (nullable, weak, nonatomic) Label *headlineLabel;
|
||||
@property (nullable, weak, nonatomic) Label *messageLabel;
|
||||
|
||||
@property (nullable, strong, nonatomic) NSLayoutConstraint *topLabelConstraint;
|
||||
@property (nullable, weak, nonatomic) NSLayoutConstraint *spaceBetweenLabels;
|
||||
|
||||
@ -14,6 +14,7 @@
|
||||
#import <MVMCoreUI/MFStyler.h>
|
||||
#import <MVMCore/MVMCoreConstants.h>
|
||||
#import <MVMCoreUI/NSLayoutConstraint+MFConvenience.h>
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
|
||||
@interface TopLabelsView ()
|
||||
|
||||
@ -54,12 +55,12 @@
|
||||
self.clipsToBounds = YES;
|
||||
|
||||
[self.headlineLabel removeFromSuperview];
|
||||
MFLabel *headlineLabel = [MFLabel commonLabelH2:YES];
|
||||
Label *headlineLabel = [Label commonLabelH2:YES];
|
||||
[self addSubview:headlineLabel];
|
||||
self.headlineLabel = headlineLabel;
|
||||
|
||||
[self.messageLabel removeFromSuperview];
|
||||
MFLabel *messageLabel = [MFLabel commonLabelB2:YES];
|
||||
Label *messageLabel = [Label commonLabelB2:YES];
|
||||
[self addSubview:messageLabel];
|
||||
self.messageLabel = messageLabel;
|
||||
|
||||
|
||||
@ -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,14 +39,14 @@ import UIKit
|
||||
}
|
||||
|
||||
// MARK: - MVMCoreUIMoleculeViewProtocol
|
||||
open override func setWithJSON(_ json: [AnyHashable : Any]?, delegate: NSObject?, additionalData: [AnyHashable : Any]?) {
|
||||
super.setWithJSON(json, delegate: delegate, additionalData: additionalData)
|
||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) {
|
||||
backgroundColor = UIColor.mfGet(forHex: backgroundColorString)
|
||||
}
|
||||
let primaryButtonMap = json?.optionalDictionaryForKey("primaryButton")
|
||||
let secondaryButtonMap = json?.optionalDictionaryForKey("secondaryButton")
|
||||
set(primaryButtonJSON: primaryButtonMap, secondaryButtonJSON: secondaryButtonMap, actionDelegate: delegate, additionalData: additionalData, buttonDelegate: delegate)
|
||||
set(primaryButtonJSON: primaryButtonMap, secondaryButtonJSON: secondaryButtonMap, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
// MARK: - Constraining
|
||||
@ -137,33 +142,24 @@ import UIKit
|
||||
}
|
||||
}
|
||||
|
||||
open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) {
|
||||
open func set(primaryButtonJSON: [AnyHashable: Any]?, secondaryButtonJSON: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
setupUI(withPrimaryButtonMap: primaryButtonJSON, secondaryButtonMap: secondaryButtonJSON, legacy: false)
|
||||
primaryButton?.setAsStandardCustom()
|
||||
secondaryButton?.setAsSecondaryCustom()
|
||||
primaryButton?.setWithJSON(primaryButtonJSON, delegate: actionDelegate as? NSObject, additionalData: additionalData)
|
||||
secondaryButton?.setWithJSON(secondaryButtonJSON, delegate: actionDelegate as? NSObject, additionalData: additionalData)
|
||||
setDefaultCustom()
|
||||
primaryButton?.setWithJSON(primaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData)
|
||||
secondaryButton?.setWithJSON(secondaryButtonJSON, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
|
||||
// MARK: - Legacy
|
||||
open func setup(withButtonMap buttonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) {
|
||||
let secondaryButtonMap = buttonMap?.optionalDictionaryForKey(KeySecondaryButton)
|
||||
let primaryButtonMap = buttonMap?.optionalDictionaryForKey(KeyPrimaryButton)
|
||||
setup(primaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, actionDelegate: actionDelegate, additionalData: additionalData, buttonDelegate: buttonDelegate)
|
||||
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)
|
||||
}
|
||||
|
||||
open func setup(primaryButtonMap: [AnyHashable: Any]?, secondaryButtonMap: [AnyHashable: Any]?, actionDelegate: NSObjectProtocol?, additionalData: [AnyHashable: Any]?, buttonDelegate: Any?) {
|
||||
setupUI(withPrimaryButtonMap: primaryButtonMap, secondaryButtonMap: secondaryButtonMap, legacy: true)
|
||||
if primaryButtonMap != nil, secondaryButtonMap != nil {
|
||||
primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
secondaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
} else if primaryButtonMap != nil {
|
||||
primaryButton?.setWithActionMap(primaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
primaryButton?.bordered = false
|
||||
} else if secondaryButtonMap != nil {
|
||||
primaryButton?.setWithActionMap(secondaryButtonMap, actionDelegate: actionDelegate as? MVMCoreActionDelegateProtocol & NSObjectProtocol, additionalData: additionalData, buttonDelegate: buttonDelegate as? ButtonDelegateProtocol)
|
||||
primaryButton?.bordered = true
|
||||
}
|
||||
public convenience init(buttonSmall small: Bool, 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) {
|
||||
@ -174,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() {
|
||||
@ -225,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,9 @@
|
||||
|
||||
// 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;
|
||||
|
||||
// Similar to above but also checks if the molecule needs to be constrained for a stack.
|
||||
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForStackWithJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject;
|
||||
|
||||
@end
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
static NSMutableDictionary <NSString *, Class>*mapping;
|
||||
dispatch_once(&onceToken, ^{
|
||||
mapping = [@{
|
||||
@"label": LabelView.class,
|
||||
@"label": Label.class,
|
||||
@"separator": SeparatorView.class,
|
||||
@"button": ButtonView.class,
|
||||
@"textButton": MFTextButton.class,
|
||||
@ -32,7 +32,8 @@
|
||||
@"standardFooter": StandardFooterView.class,
|
||||
@"caretView": CaretView.class,
|
||||
@"caretButton": CaretButton.class,
|
||||
@"textField" : MFTextField.class
|
||||
@"textField" : MFTextField.class,
|
||||
@"checkbox" : MVMCoreUICheckBox.class
|
||||
} mutableCopy];
|
||||
});
|
||||
return mapping;
|
||||
@ -45,25 +46,38 @@
|
||||
|
||||
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForName:(nonnull NSString *)name {
|
||||
Class class = [self.moleculeMapping objectForKey:name];
|
||||
if (class) {
|
||||
UIView <MVMCoreUIMoleculeViewProtocol>*view = [[class alloc] init];
|
||||
if ([view respondsToSelector:@selector(setAsMolecule)]) {
|
||||
[view setAsMolecule];
|
||||
}
|
||||
return view;
|
||||
if (!class) {
|
||||
return nil;
|
||||
}
|
||||
return nil;
|
||||
UIView <MVMCoreUIMoleculeViewProtocol>*molecule = [[class alloc] init];
|
||||
if ([molecule respondsToSelector:@selector(setAsMolecule)]) {
|
||||
[molecule setAsMolecule];
|
||||
}
|
||||
return molecule;
|
||||
}
|
||||
|
||||
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForJSON:(nonnull NSDictionary *)json delegate:(nullable NSObject *)delegate {
|
||||
NSString *moleculeName = [json string:@"moleculeName"];
|
||||
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject {
|
||||
NSString *moleculeName = [json string:KeyMoleculeName];
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
- (nullable UIView <MVMCoreUIMoleculeViewProtocol>*)getMoleculeForStackWithJSON:(nonnull NSDictionary *)json delegateObject:(nullable DelegateObject *)delegateObject {
|
||||
NSString *moleculeName = [json string:KeyMoleculeName];
|
||||
if (!moleculeName) {
|
||||
return nil;
|
||||
}
|
||||
UIView <MVMCoreUIMoleculeViewProtocol>*molecule = [self getMoleculeForName:moleculeName];
|
||||
if ([molecule respondsToSelector:@selector(needsToBeConstrained)] && [molecule needsToBeConstrained]) {
|
||||
molecule = [[ViewConstrainingView alloc] initWithMolecule:molecule alignment:[molecule respondsToSelector:@selector(moleculeAlignment)] ? [molecule moleculeAlignment] : UIStackViewAlignmentFill];
|
||||
}
|
||||
[molecule setWithJSON:json delegateObject:delegateObject additionalData:nil];
|
||||
return molecule;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -21,7 +21,8 @@
|
||||
viewControllerMapping = [@{
|
||||
@"textFieldListForm" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[TextFieldListFormViewController class]],
|
||||
@"moleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackTemplate class]],
|
||||
@"centerMoleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackCenteredTemplate class]]
|
||||
@"centerMoleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackCenteredTemplate class]],
|
||||
@"moleculeList" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeListTemplate class]]
|
||||
} mutableCopy];
|
||||
});
|
||||
return viewControllerMapping;
|
||||
|
||||
@ -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,8 @@
|
||||
#import "UIColor+MFConvenience.h"
|
||||
#import "NSLayoutConstraint+MFConvenience.h"
|
||||
#import "MVMCoreUISplitViewController.h"
|
||||
@import MVMCore.MVMCoreDispatchUtility;
|
||||
#import <MVMCoreUI/MVMCoreUIUtility.h>
|
||||
|
||||
CGFloat const PaddingDefault = 24;
|
||||
CGFloat const PaddingDefaultHorizontalSpacing = 32;
|
||||
@ -88,6 +90,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 {
|
||||
@ -935,7 +948,8 @@ CGFloat const LabelWithInternalButtonLineSpace = 2;
|
||||
if ([times containsObject:@"DD"]) {
|
||||
[timeString appendString:[NSString stringWithFormat:@"%02ld",days]];
|
||||
if (timeUnit == MFTimeFormatNormal) {
|
||||
NSString *dayUnit = (days <= 1) ? @" day": @" days";
|
||||
NSString *dayKey = (days <= 1) ? @"CountDownDay": @"CountDownDays";
|
||||
NSString *dayUnit = [MVMCoreUIUtility hardcodedStringWithKey:dayKey];
|
||||
[timeString appendString:dayUnit];
|
||||
} else if (timeUnit == MFTimeFormatColon && ![[times lastObject] isEqualToString:@"DD"]) {
|
||||
[timeString appendString:@" : "];
|
||||
@ -950,7 +964,8 @@ CGFloat const LabelWithInternalButtonLineSpace = 2;
|
||||
}
|
||||
[timeString appendString:[NSString stringWithFormat:@"%02d",hours]];
|
||||
if (timeUnit == MFTimeFormatNormal) {
|
||||
NSString *hourUnit = (hours <= 1) ? @" hour": @" hours";
|
||||
NSString *hourKey = (hours <= 1) ? @"CountDownHour": @"CountDownHours";
|
||||
NSString *hourUnit = [MVMCoreUIUtility hardcodedStringWithKey:hourKey];
|
||||
[timeString appendString:hourUnit];
|
||||
} else if (timeUnit == MFTimeFormatColon && ![[times lastObject] isEqualToString:@"HH"]) {
|
||||
[timeString appendString:@" : "];
|
||||
@ -969,7 +984,8 @@ CGFloat const LabelWithInternalButtonLineSpace = 2;
|
||||
}
|
||||
[timeString appendString:[NSString stringWithFormat:@"%02d",minutes]];
|
||||
if (timeUnit == MFTimeFormatNormal) {
|
||||
NSString *minuteUnit = (minutes <= 1) ? @" min": @" mins";
|
||||
NSString *minKey = (minutes <= 1) ? @"CountDownMin": @"CountDownMins";
|
||||
NSString *minuteUnit = [MVMCoreUIUtility hardcodedStringWithKey:minKey];
|
||||
[timeString appendString:minuteUnit];
|
||||
} else if (timeUnit == MFTimeFormatColon && ![[times lastObject] isEqualToString:@"MM"]) {
|
||||
[timeString appendString:@" : "];
|
||||
@ -993,7 +1009,8 @@ CGFloat const LabelWithInternalButtonLineSpace = 2;
|
||||
}
|
||||
[timeString appendString:[NSString stringWithFormat:@"%02d",seconds]];
|
||||
if (timeUnit == MFTimeFormatNormal) {
|
||||
NSString *secondUnit = (seconds <= 1) ? @" sec": @" secs";
|
||||
NSString *secondKey = (seconds <= 1) ? @"CountDownSec": @"CountDownSecs";
|
||||
NSString *secondUnit = [MVMCoreUIUtility hardcodedStringWithKey:secondKey];
|
||||
[timeString appendString:secondUnit];
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
// Tab
|
||||
"AccTab" = ", tab";
|
||||
"AccTabHint" = "Double tap to select.";
|
||||
"AccTabIndex" = ", %ld of %ld";
|
||||
// top alert
|
||||
"toptabbar_tab_selected" = ", tab, Selected";
|
||||
"AccTopAlertClosed" = "Top alert notification is closed.";
|
||||
@ -39,3 +40,12 @@
|
||||
"AccOn" = "on";
|
||||
"AccOff" = "off";
|
||||
"AccToggleHint" = "double tap to toggle";
|
||||
//Styler
|
||||
"CountDownDay" = " day";
|
||||
"CountDownHour" = " hour";
|
||||
"CountDownMin" = " min";
|
||||
"CountDownSec" = " sec";
|
||||
"CountDownDays" = " days";
|
||||
"CountDownHours" = " hours";
|
||||
"CountDownMins" = " mins";
|
||||
"CountDownSecs" = " secs";
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
// Tab
|
||||
"AccTab" = ", pestaña";
|
||||
"AccTabHint" = "Toca dos veces para seleccionar.";
|
||||
"AccTabIndex" = ", %ld de %ld";
|
||||
// top alert
|
||||
"toptabbar_tab_selected" = ", pestaña, Seleccionado";
|
||||
"AccTopAlertClosed" = "La notificación de alerta máxima está desactivada.";
|
||||
@ -38,3 +39,12 @@
|
||||
"AccOn" = "encendido";
|
||||
"AccOff" = "apagado";
|
||||
"AccToggleHint" = "toca dos veces para alternar";
|
||||
//Styler
|
||||
"CountDownDay" = " día";
|
||||
"CountDownHour" = " hora";
|
||||
"CountDownMin" = " min";
|
||||
"CountDownSec" = " seg";
|
||||
"CountDownDays" = " días";
|
||||
"CountDownHours" = " horas";
|
||||
"CountDownMins" = " min";
|
||||
"CountDownSecs" = " seg";
|
||||
|
||||
@ -10,6 +10,7 @@
|
||||
// Tab
|
||||
"AccTab" = ", pestaña";
|
||||
"AccTabHint" = "Toca dos veces para seleccionar.";
|
||||
"AccTabIndex" = ", %ld de %ld";
|
||||
// top alert
|
||||
"toptabbar_tab_selected" = ", pestaña, Seleccionado";
|
||||
"AccTopAlertClosed" = "La notificación de alerta máxima está desactivada.";
|
||||
@ -38,3 +39,12 @@
|
||||
"AccOn" = "encendido";
|
||||
"AccOff" = "apagado";
|
||||
"AccToggleHint" = "toca dos veces para alternar";
|
||||
//Styler
|
||||
"CountDownDay" = " día";
|
||||
"CountDownHour" = " hora";
|
||||
"CountDownMin" = " min";
|
||||
"CountDownSec" = " seg";
|
||||
"CountDownDays" = " días";
|
||||
"CountDownHours" = " horas";
|
||||
"CountDownMins" = " min";
|
||||
"CountDownSecs" = " seg";
|
||||
|
||||
68
MVMCoreUI/Templates/MoleculeListTemplate.swift
Normal file
68
MVMCoreUI/Templates/MoleculeListTemplate.swift
Normal file
@ -0,0 +1,68 @@
|
||||
//
|
||||
// MoleculeListTemplate.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/18/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
open class MoleculeListTemplate: ThreeLayerTableViewController {
|
||||
|
||||
open override func registerWithTable() {
|
||||
super.registerWithTable()
|
||||
guard let molecules = loadObject?.pageJSON?.arrayForKey(KeyMolecules) else {
|
||||
return
|
||||
}
|
||||
for case let molecule as Dictionary<AnyHashable, Any> in molecules {
|
||||
if let moleculeName = molecule.optionalStringForKey(KeyMoleculeName) {
|
||||
tableView?.register(MoleculeTableViewCell.self, forCellReuseIdentifier: moleculeName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
open override func viewForTop() -> UIView {
|
||||
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else {
|
||||
return super.viewForTop()
|
||||
}
|
||||
return molecule
|
||||
}
|
||||
|
||||
override open func viewForBottom() -> UIView {
|
||||
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else {
|
||||
return viewForBottom()
|
||||
}
|
||||
return molecule
|
||||
}
|
||||
|
||||
open override func newDataBuildScreen() {
|
||||
super.newDataBuildScreen()
|
||||
registerWithTable()
|
||||
}
|
||||
|
||||
open override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
|
||||
if let moleculeName = loadObject?.pageJSON?.stringOptionalWithChainOfKeysOrIndexes([KeyMolecules,indexPath.row,KeyMoleculeName]), let theClass = MVMCoreUIMoleculeMappingObject.shared()?.moleculeMapping?[moleculeName] as? MVMCoreUIMoleculeViewProtocol.Type,
|
||||
let estimatedHeightForRow = theClass.estimatedHeightForRow {
|
||||
return estimatedHeightForRow()
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
open override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return loadObject?.pageJSON?.arrayForKey(KeyMolecules).count ?? 0
|
||||
}
|
||||
|
||||
open override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
guard let molecule = loadObject?.pageJSON?.optionalDictionaryWithChainOfKeysOrIndexes([KeyMolecules,indexPath.row]),
|
||||
let moleculeName = molecule.optionalStringForKey(KeyMoleculeName),
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeName) as? MoleculeTableViewCell else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
let delegate = delegateObject()
|
||||
cell.setWithJSON(molecule, delegateObject: delegate, additionalData: nil)
|
||||
cell.setSeparatorWithJSON(loadObject?.pageJSON?.optionalDictionaryForKey("separator"), delegateObject: delegate, additionalData: nil, indexPath: indexPath)
|
||||
cell.updateView(tableView.bounds.width)
|
||||
return cell
|
||||
}
|
||||
}
|
||||
@ -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()?.getMoleculeForStack(withJSON: 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()?.getMoleculeForStack(withJSON: moleculeJSON, delegateObject: delegateObject()) else {
|
||||
return nil
|
||||
}
|
||||
return molecule
|
||||
|
||||
@ -12,11 +12,11 @@ public class MoleculeStackTemplate: ThreeLayerViewController {
|
||||
|
||||
|
||||
public override func spaceBetweenTopAndMiddle() -> CGFloat? {
|
||||
return PaddingTwo
|
||||
return 0
|
||||
}
|
||||
|
||||
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()?.getMoleculeForStack(withJSON: 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()?.getMoleculeForStack(withJSON: 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
|
||||
|
||||
|
||||
@ -41,6 +41,9 @@
|
||||
- (void)expandStatusBarView;
|
||||
- (void)collapseStatusBarView;
|
||||
|
||||
/// reset status bar background color, when backgroundColor is nil corresponding background color will be set based on style
|
||||
- (void)resetDefaultBackgroundColor:(nullable UIColor *)backgroundColor basedOnStatusBarStyle:(UIStatusBarStyle)style;
|
||||
|
||||
// Can be subclassed for custom views.
|
||||
- (nonnull MVMCoreUITopAlertBaseView *)topAlertViewForTopAlertObject:(nullable MVMCoreTopAlertObject *)topAlertObject animationDelegate:(nonnull id <MVMCoreTopAlertAnimationDelegateProtocol>)animationDelegate statusBarColor:(UIColor *_Nullable *_Nullable)statusBarColor;
|
||||
|
||||
|
||||
@ -189,7 +189,6 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed.";
|
||||
[weakSelf.superview layoutIfNeeded];
|
||||
} completion:^(BOOL finished) {
|
||||
[weakSelf.animationDelegate topAlertViewFinishAnimation];
|
||||
[weakSelf setStatusBarColor:[UIColor whiteColor] statusBarStyle:UIStatusBarStyleDefault];
|
||||
UIAccessibilityPostNotification(UIAccessibilityLayoutChangedNotification, nil);
|
||||
|
||||
UIView *view = weakSelf.currentAlert;
|
||||
@ -204,6 +203,9 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed.";
|
||||
[operation markAsFinished];
|
||||
completionHandler(finished);
|
||||
weakSelf.topAlertObject = nil;
|
||||
[MVMCoreDispatchUtility performBlockOnMainThread:^{
|
||||
[weakSelf setStatusBarColor:[UIColor whiteColor] statusBarStyle:UIStatusBarStyleDefault];
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
}];
|
||||
@ -242,4 +244,18 @@ NSString * const MFAccTopAlertClosed = @"Top alert notification is closed.";
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)resetDefaultBackgroundColor:(UIColor *)backgroundColor basedOnStatusBarStyle:(UIStatusBarStyle)style {
|
||||
if (!self.topAlertObject) {
|
||||
UIColor *defaultStatusBarBackgroundColor = backgroundColor;
|
||||
if (!defaultStatusBarBackgroundColor) {
|
||||
defaultStatusBarBackgroundColor = style == UIStatusBarStyleDefault ? [UIColor whiteColor] : [UIColor blackColor];
|
||||
}
|
||||
|
||||
//color doesn't match the current default value
|
||||
if (!CGColorEqualToColor(defaultStatusBarBackgroundColor.CGColor, self.statusBarView.backgroundColor.CGColor)) {
|
||||
self.statusBarView.backgroundColor = defaultStatusBarBackgroundColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -13,6 +13,9 @@
|
||||
|
||||
extern NSString * const KeyScreenHeading;
|
||||
|
||||
extern NSString * const KeyMolecules;
|
||||
extern NSString * const KeyMoleculeName;
|
||||
|
||||
extern NSString * const KeyDisableButton;
|
||||
|
||||
extern NSString * const KeyValue;
|
||||
@ -35,6 +38,9 @@ extern NSString * const KeyTextColor;
|
||||
extern NSString * const KeyIsHidden;
|
||||
extern NSString * const KeyIsOpaque;
|
||||
|
||||
extern NSString * const KeyFieldKey;
|
||||
extern NSString * const KeyRequired;
|
||||
|
||||
#pragma mark - Values
|
||||
|
||||
extern NSString * const StringY;
|
||||
|
||||
@ -12,12 +12,17 @@
|
||||
|
||||
NSString * const KeyScreenHeading = @"screenHeading";
|
||||
|
||||
NSString * const KeyMolecules = @"molecules";
|
||||
NSString * const KeyMoleculeName = @"moleculeName";
|
||||
|
||||
NSString * const KeyDisableButton = @"disableAction";
|
||||
|
||||
NSString * const KeyValue = @"value";
|
||||
NSString * const KeyLabel = @"label";
|
||||
NSString * const KeyDisable = @"disable";
|
||||
NSString * const KeyFieldName = @"fieldName";
|
||||
NSString * const KeyFieldKey = @"fieldKey";
|
||||
NSString * const KeyRequired = @"required";
|
||||
|
||||
NSString * const KeyHideMainMenu = @"hideMainMenu";
|
||||
NSString * const KeyProgressPercent = @"progressPercent";
|
||||
@ -34,6 +39,7 @@ NSString * const KeyTextColor = @"textColor";
|
||||
NSString * const KeyIsHidden = @"isHidden";
|
||||
NSString * const KeyIsOpaque = @"isOpaque";
|
||||
|
||||
|
||||
#pragma mark - Values
|
||||
|
||||
NSString * const StringY = @"Y";
|
||||
|
||||
Loading…
Reference in New Issue
Block a user