diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 8c8eb55e..aed43ac1 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -7,12 +7,22 @@ objects = { /* Begin PBXBuildFile section */ - D206997721FB8A0B00CAE0DE /* MVMCoreUINavigationControllerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationControllerViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationControllerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D206997621FB8A0B00CAE0DE /* MVMCoreUINavigationControllerViewController.m */; }; - D28B4F8A21FF967C00712C7A /* MVMCoreUIObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */; }; 01DF55E021F8FAA800CC099B /* MFTextFieldListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */; }; 01DF567021FA5AB300CC099B /* MVMCoreUITextFieldListFormViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 01DF566F21FA5AB300CC099B /* MVMCoreUITextFieldListFormViewController.swift */; }; + D206997721FB8A0B00CAE0DE /* MVMCoreUINavigationControllerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationControllerViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationControllerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D206997621FB8A0B00CAE0DE /* MVMCoreUINavigationControllerViewController.m */; }; + D22D1F1A220341F60077CEC0 /* MVMCoreUICheckBox.h in Headers */ = {isa = PBXBuildFile; fileRef = D22D1F18220341F50077CEC0 /* MVMCoreUICheckBox.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D22D1F1B220341F60077CEC0 /* MVMCoreUICheckBox.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F19220341F50077CEC0 /* MVMCoreUICheckBox.m */; }; + D22D1F1E220343560077CEC0 /* MVMCoreUICheckMarkView.h in Headers */ = {isa = PBXBuildFile; fileRef = D22D1F1C220343560077CEC0 /* MVMCoreUICheckMarkView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F1D220343560077CEC0 /* MVMCoreUICheckMarkView.m */; }; + D22D1F46220496A30077CEC0 /* MVMCoreUISwitch.h in Headers */ = {isa = PBXBuildFile; fileRef = D22D1F44220496A30077CEC0 /* MVMCoreUISwitch.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D22D1F47220496A30077CEC0 /* MVMCoreUISwitch.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */; }; + D22D1F562204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = D22D1F542204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F552204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m */; }; + D22D1F5B2204D2C00077CEC0 /* MVMCoreUIThreeLayerViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = D22D1F592204D2C00077CEC0 /* MVMCoreUIThreeLayerViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D22D1F5C2204D2C00077CEC0 /* MVMCoreUIThreeLayerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F5A2204D2C00077CEC0 /* MVMCoreUIThreeLayerViewController.m */; }; + D28B4F8A21FF967C00712C7A /* MVMCoreUIObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */; }; D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */; }; D29770C921F7C4AE00B2F0D0 /* TopLabelsView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770EE21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m */; }; @@ -21,8 +31,8 @@ D29770F521F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770F121F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m */; }; D29770F821F7C73800B2F0D0 /* PrimaryButtonView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770F621F7C73800B2F0D0 /* PrimaryButtonView.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29770F921F7C73800B2F0D0 /* PrimaryButtonView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770F721F7C73800B2F0D0 /* PrimaryButtonView.m */; }; - D29770FC21F7C77400B2F0D0 /* TextFieldView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770FA21F7C77400B2F0D0 /* TextFieldView.m */; }; - D29770FD21F7C77400B2F0D0 /* TextFieldView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770FB21F7C77400B2F0D0 /* TextFieldView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770FA21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m */; }; + D29770FD21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29770FB21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF0D121E404D4003B2FB9 /* MVMCoreUI.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF0CF21E404D4003B2FB9 /* MVMCoreUI.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF0E221E4F3B6003B2FB9 /* MVMCoreUILargeHeaderSingleLabelTemplate.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF0E021E4F3B6003B2FB9 /* MVMCoreUILargeHeaderSingleLabelTemplate.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF0E321E4F3B6003B2FB9 /* MVMCoreUILargeHeaderSingleLabelTemplate.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF0E121E4F3B6003B2FB9 /* MVMCoreUILargeHeaderSingleLabelTemplate.m */; }; @@ -148,12 +158,22 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationControllerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUINavigationControllerViewController.h; sourceTree = ""; }; - D206997621FB8A0B00CAE0DE /* MVMCoreUINavigationControllerViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUINavigationControllerViewController.m; sourceTree = ""; }; - D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIObject.h; sourceTree = ""; }; - D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIObject.m; sourceTree = ""; }; 01DF55DF21F8FAA800CC099B /* MFTextFieldListView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MFTextFieldListView.swift; sourceTree = ""; }; 01DF566F21FA5AB300CC099B /* MVMCoreUITextFieldListFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MVMCoreUITextFieldListFormViewController.swift; sourceTree = ""; }; + D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationControllerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUINavigationControllerViewController.h; sourceTree = ""; }; + D206997621FB8A0B00CAE0DE /* MVMCoreUINavigationControllerViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUINavigationControllerViewController.m; sourceTree = ""; }; + D22D1F18220341F50077CEC0 /* MVMCoreUICheckBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUICheckBox.h; sourceTree = ""; }; + D22D1F19220341F50077CEC0 /* MVMCoreUICheckBox.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUICheckBox.m; sourceTree = ""; }; + D22D1F1C220343560077CEC0 /* MVMCoreUICheckMarkView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUICheckMarkView.h; sourceTree = ""; }; + D22D1F1D220343560077CEC0 /* MVMCoreUICheckMarkView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUICheckMarkView.m; sourceTree = ""; }; + D22D1F44220496A30077CEC0 /* MVMCoreUISwitch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUISwitch.h; sourceTree = ""; }; + D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUISwitch.m; sourceTree = ""; }; + D22D1F542204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIStackableViewController.h; sourceTree = ""; }; + D22D1F552204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIStackableViewController.m; sourceTree = ""; }; + D22D1F592204D2C00077CEC0 /* MVMCoreUIThreeLayerViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIThreeLayerViewController.h; sourceTree = ""; }; + D22D1F5A2204D2C00077CEC0 /* MVMCoreUIThreeLayerViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIThreeLayerViewController.m; sourceTree = ""; }; + D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIObject.h; sourceTree = ""; }; + D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIObject.m; sourceTree = ""; }; D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsView.m; sourceTree = ""; }; D29770C721F7C4AE00B2F0D0 /* TopLabelsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TopLabelsView.h; sourceTree = ""; }; D29770EE21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsAndBottomButtonsTableViewController.m; sourceTree = ""; }; @@ -162,8 +182,8 @@ D29770F121F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsAndBottomButtonsViewController.m; sourceTree = ""; }; D29770F621F7C73800B2F0D0 /* PrimaryButtonView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PrimaryButtonView.h; sourceTree = ""; }; D29770F721F7C73800B2F0D0 /* PrimaryButtonView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PrimaryButtonView.m; sourceTree = ""; }; - D29770FA21F7C77400B2F0D0 /* TextFieldView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TextFieldView.m; sourceTree = ""; }; - D29770FB21F7C77400B2F0D0 /* TextFieldView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TextFieldView.h; sourceTree = ""; }; + D29770FA21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUITextFieldView.m; sourceTree = ""; }; + D29770FB21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MVMCoreUITextFieldView.h; sourceTree = ""; }; D29DF0CC21E404D4003B2FB9 /* MVMCoreUI.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MVMCoreUI.framework; sourceTree = BUILT_PRODUCTS_DIR; }; D29DF0CF21E404D4003B2FB9 /* MVMCoreUI.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUI.h; sourceTree = ""; }; D29DF0D021E404D4003B2FB9 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -305,6 +325,19 @@ /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + D22D1F582204D2590077CEC0 /* LegacyControllers */ = { + isa = PBXGroup; + children = ( + D29DF29321E7ADB8003B2FB9 /* StackableViewController.h */, + D29DF28E21E7ADB8003B2FB9 /* StackableViewController.m */, + D29770F021F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.h */, + D29770F121F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m */, + D29770EF21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h */, + D29770EE21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m */, + ); + path = LegacyControllers; + sourceTree = ""; + }; D29DF0C221E404D4003B2FB9 = { isa = PBXGroup; children = ( @@ -331,6 +364,7 @@ D29DF13321E68604003B2FB9 /* Styles */, D29DF11021E6805F003B2FB9 /* Categories */, D29DF11921E68467003B2FB9 /* Containers */, + D22D1F582204D2590077CEC0 /* LegacyControllers */, D29DF10F21E67A7D003B2FB9 /* BaseControllers */, D29DF11E21E6851E003B2FB9 /* TopAlert */, D29DF10D21E67A70003B2FB9 /* Atoms */, @@ -394,14 +428,12 @@ D29DF28D21E7ADB8003B2FB9 /* ProgrammaticScrollViewController.m */, D29DF29221E7ADB8003B2FB9 /* MFProgrammaticTableViewController.h */, D29DF29421E7ADB8003B2FB9 /* MFProgrammaticTableViewController.m */, - D29DF29321E7ADB8003B2FB9 /* StackableViewController.h */, - D29DF28E21E7ADB8003B2FB9 /* StackableViewController.m */, + D22D1F542204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h */, + D22D1F552204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m */, D29DF2CC21E7C104003B2FB9 /* MFLoadingViewController.h */, D29DF2CD21E7C104003B2FB9 /* MFLoadingViewController.m */, - D29770F021F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.h */, - D29770F121F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m */, - D29770EF21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h */, - D29770EE21F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m */, + D22D1F592204D2C00077CEC0 /* MVMCoreUIThreeLayerViewController.h */, + D22D1F5A2204D2C00077CEC0 /* MVMCoreUIThreeLayerViewController.m */, ); path = BaseControllers; sourceTree = ""; @@ -528,8 +560,14 @@ D29DF2B221E7B76D003B2FB9 /* MFLoadingSpinner.m */, D29DF32321ED0DA2003B2FB9 /* TextButtonView.h */, D29DF32221ED0DA2003B2FB9 /* TextButtonView.m */, - D29770FB21F7C77400B2F0D0 /* TextFieldView.h */, - D29770FA21F7C77400B2F0D0 /* TextFieldView.m */, + D29770FB21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h */, + D29770FA21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m */, + D22D1F1C220343560077CEC0 /* MVMCoreUICheckMarkView.h */, + D22D1F1D220343560077CEC0 /* MVMCoreUICheckMarkView.m */, + D22D1F18220341F50077CEC0 /* MVMCoreUICheckBox.h */, + D22D1F19220341F50077CEC0 /* MVMCoreUICheckBox.m */, + D22D1F44220496A30077CEC0 /* MVMCoreUISwitch.h */, + D22D1F45220496A30077CEC0 /* MVMCoreUISwitch.m */, ); path = Views; sourceTree = ""; @@ -659,6 +697,7 @@ D29DF2B021E7B3A4003B2FB9 /* MFTextView.h in Headers */, D29DF2A921E7B2F9003B2FB9 /* MVMCoreUIConstants.h in Headers */, D29DF25221E6A177003B2FB9 /* MFMdnTextField.h in Headers */, + D22D1F1A220341F60077CEC0 /* MVMCoreUICheckBox.h in Headers */, D29DF29921E7ADB8003B2FB9 /* ProgrammaticScrollViewController.h in Headers */, D29DF11C21E684A9003B2FB9 /* MVMCoreUISplitViewController.h in Headers */, D29DF29B21E7ADB9003B2FB9 /* StackableViewController.h in Headers */, @@ -670,7 +709,11 @@ D29DF11521E6805F003B2FB9 /* UIColor+MFConvenience.h in Headers */, D29DF2BC21E7BEA4003B2FB9 /* TopTabbar.h in Headers */, D29DF25921E6A22D003B2FB9 /* MFButtonProtocol.h in Headers */, + D22D1F46220496A30077CEC0 /* MVMCoreUISwitch.h in Headers */, + D22D1F5B2204D2C00077CEC0 /* MVMCoreUIThreeLayerViewController.h in Headers */, + D22D1F1E220343560077CEC0 /* MVMCoreUICheckMarkView.h in Headers */, D29DF28421E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.h in Headers */, + D22D1F562204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h in Headers */, D29DF2CE21E7C104003B2FB9 /* MFLoadingViewController.h in Headers */, D29DF12A21E6851E003B2FB9 /* MVMCoreUITopAlertView.h in Headers */, D29DF27521E79E81003B2FB9 /* MVMCoreUILoggingHandler.h in Headers */, @@ -703,7 +746,7 @@ D29DF24E21E6A177003B2FB9 /* MFDigitTextField.h in Headers */, D29770F321F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h in Headers */, D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */, - D29770FD21F7C77400B2F0D0 /* TextFieldView.h in Headers */, + D29770FD21F7C77400B2F0D0 /* MVMCoreUITextFieldView.h in Headers */, D29DF17421E69E1F003B2FB9 /* MFCustomButton.h in Headers */, D29DF29721E7ADB8003B2FB9 /* MFScrollingViewController.h in Headers */, D29DF26F21E6AA0B003B2FB9 /* FLAnimatedImageView.h in Headers */, @@ -801,6 +844,7 @@ D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */, D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */, D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */, + D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */, D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */, D29DF25321E6A177003B2FB9 /* MFDigitTextField.m in Sources */, D29770F921F7C73800B2F0D0 /* PrimaryButtonView.m in Sources */, @@ -811,6 +855,7 @@ D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */, D29DF12E21E6851E003B2FB9 /* MVMCoreUITopAlertView.m in Sources */, D29DF2CF21E7C104003B2FB9 /* MFLoadingViewController.m in Sources */, + D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */, 01DF567021FA5AB300CC099B /* MVMCoreUITextFieldListFormViewController.swift in Sources */, D29DF27621E79E81003B2FB9 /* MVMCoreUILoggingHandler.m in Sources */, D29DF24D21E6A177003B2FB9 /* MFTextField.m in Sources */, @@ -821,6 +866,7 @@ D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */, D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */, D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */, + D22D1F5C2204D2C00077CEC0 /* MVMCoreUIThreeLayerViewController.m in Sources */, D29DF2EF21ECEAE1003B2FB9 /* MFFonts.m in Sources */, D29DF2AE21E7B3A4003B2FB9 /* MFTextView.m in Sources */, D29DF18121E69E50003B2FB9 /* MFView.m in Sources */, @@ -839,6 +885,7 @@ D29DF25D21E6A2B6003B2FB9 /* DashLine.m in Sources */, D29DF29521E7ADB8003B2FB9 /* ProgrammaticScrollViewController.m in Sources */, D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */, + D22D1F47220496A30077CEC0 /* MVMCoreUISwitch.m in Sources */, D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */, D29DF17B21E69E1F003B2FB9 /* PrimaryButton.m in Sources */, D29DF11D21E684A9003B2FB9 /* MVMCoreUISplitViewController.m in Sources */, @@ -848,7 +895,7 @@ D29DF17821E69E1F003B2FB9 /* MFCaretButton.m in Sources */, D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */, D29DF26C21E6AA0B003B2FB9 /* FLAnimatedImage.m in Sources */, - D29770FC21F7C77400B2F0D0 /* TextFieldView.m in Sources */, + D29770FC21F7C77400B2F0D0 /* MVMCoreUITextFieldView.m in Sources */, D29DF25121E6A177003B2FB9 /* MFDigitTextBox.m in Sources */, D29DF13221E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.m in Sources */, D29DF0E321E4F3B6003B2FB9 /* MVMCoreUILargeHeaderSingleLabelTemplate.m in Sources */, @@ -857,6 +904,7 @@ D29DF2BE21E7BEA4003B2FB9 /* TopTabbar.m in Sources */, D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */, D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */, + D22D1F1B220341F60077CEC0 /* MVMCoreUICheckBox.m in Sources */, D29DF2CB21E7BFCC003B2FB9 /* MFSizeThreshold.m in Sources */, D29770F521F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsViewController.m in Sources */, ); diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUICheckBox.h b/MVMCoreUI/Atoms/Views/MVMCoreUICheckBox.h new file mode 100644 index 00000000..8a9ab067 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/MVMCoreUICheckBox.h @@ -0,0 +1,61 @@ +// +// MVMCoreUICheckBox.h +// myverizon +// +// Created by Suresh, Kamlesh on 11/25/15. +// Copyright © 2015 Verizon Wireless. All rights reserved. +// + +#import +#import +#import +#import +@class MFSizeObject; + +@interface MVMCoreUICheckBox : UIControl + +@property (nullable, weak, nonatomic) MVMCoreUICheckMarkView *checkMark; +@property (readonly, nonatomic) BOOL isSelected; +@property (nullable, strong, nonatomic) MFSizeObject *sizeObject; + +//?????? +@property (nullable, strong, nonatomic) UIColor *checkedColor; +@property (nullable, strong, nonatomic) UIColor *unCheckedColor; + +// Label to the right of the check box. +@property (nullable, weak, nonatomic) MFLabel *descriptionLabel; + +// Setter for the descriptionLabel.text. Also sets the accessibility text. +@property (nullable, strong, nonatomic) NSString *descriptionText; +@property (nullable, strong, nonatomic) NSAttributedString *descriptionAttributedText; + +// A block that is called when the switch is selected. +@property (nullable, copy, nonatomic) void (^switchSelected)(BOOL selected); + +//convenient method to get a check box ++ (nullable instancetype)mfCheckBox; ++ (nullable instancetype)mfCheckBoxWithCheckedColor:(nullable UIColor *)checkedColor unCheckColor:(nullable UIColor *)unCheckedColor text:(nullable NSString *)text; ++ (nullable instancetype)mfCheckBoxWithCheckedColor:(nullable UIColor *)checkedColor unCheckColor:(nullable UIColor *)unCheckedColor atributedText:(nullable NSAttributedString *)attributedText; +//Check mark with rounded rect (Prepay - corner radius = 5) ++ (nullable instancetype)mfCheckBoxWithRoundedRect; + +// convenient init +- (nullable instancetype)initWithCheckedColor:(nullable UIColor *)checkedColor unCheckColor:(nullable UIColor *)unCheckedColor text:(nullable NSString *)text; +- (nullable instancetype)initWithCheckedColor:(nullable UIColor *)checkedColor unCheckColor:(nullable UIColor *)unCheckedColor attributedText:(nullable NSAttributedString *)attributedText; +- (nullable instancetype)initWithCheckMarkView:(nullable MVMCoreUICheckMarkView *)checkMarkView checkedColor:(nullable UIColor *)checkedColor unCheckColor:(nullable UIColor *)unCheckedColor text:(nullable NSString *)text; +- (nullable instancetype)initWithCheckMarkView:(nullable MVMCoreUICheckMarkView *)checkMarkView checkedColor:(nullable UIColor *)checkedColor unCheckColor:(nullable UIColor *)unCheckedColor attributedText:(nullable NSAttributedString *)attributedText; + +//configures +- (void)setSelected:(BOOL)selected; +- (void)setSelected:(BOOL)selected animated:(BOOL)animated; +- (void)setColor:(nullable UIColor *)color forState:(UIControlState)state; +- (void)setCheckBoxBorder:(nullable UIColor *)color; + +// helper +- (void)enable:(BOOL)enable; + +//accessibility +- (void)setValueForAccessibilityText:(nullable NSString *)text; +- (void)hideDescriptionLabelAndPinCheckboxToRight; + +@end diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUICheckBox.m b/MVMCoreUI/Atoms/Views/MVMCoreUICheckBox.m new file mode 100644 index 00000000..ad6bf187 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/MVMCoreUICheckBox.m @@ -0,0 +1,378 @@ +// +// MVMCoreUICheckBox.m +// myverizon +// +// Created by Suresh, Kamlesh on 11/25/15. +// Update For new Design by Chris Yang on 2/20/26 +// Copyright © 2015 Verizon Wireless. All rights reserved. +// + +#import "MVMCoreUICheckBox.h" +@import MVMCore.MVMCoreDispatchUtility; +@import MVMCore.MVMCoreGetterUtility; +#import "MFSizeObject.h" +#import "MVMCoreUICommonViewsUtility.h" +#import "NSLayoutConstraint+MFConvenience.h" +#import "UIColor+MFConvenience.h" +#import "MVMCoreUIUtility.h" +#import "MFStyler.h" + +static const CGFloat FaultTolerance = 20.f; +static const CGFloat CheckBoxHeightWidth = 18.0; +@interface MVMCoreUICheckBox () + +@property (nonatomic, readwrite) BOOL isSelected; +@property (weak, nonatomic) UIView *checkedSquare; +@property (weak, nonatomic) UIView *containerView; +@property (nullable, nonatomic, strong) UIColor *checkedBoxBorderColor; +@property (nullable, nonatomic, strong) UIColor *checkMarkLineColor; + +//accessibility +@property (nullable, strong, nonatomic) NSString *accessibilityText; +//Rounded rect check mark +@property (assign, nonatomic)BOOL isRoundRectCheckMark; + +@property (nullable, strong, nonatomic) NSLayoutConstraint *checkboxRightPinConstraint; +@property (nullable, strong, nonatomic) NSLayoutConstraint *descriptionLabelLeadingConstraint; + +@property (nullable, strong, nonatomic) NSLayoutConstraint *checkboxWidth; +@property (nullable, strong, nonatomic) NSLayoutConstraint *checkboxHeight; + +@end + +@implementation MVMCoreUICheckBox + +#pragma mark - convenient class methods + ++ (instancetype)mfCheckBox { + MVMCoreUICheckBox *checkBox = [[self alloc] initWithFrame:CGRectZero]; + checkBox.translatesAutoresizingMaskIntoConstraints = NO; + return checkBox ; +} + ++ (nullable instancetype)mfCheckBoxWithRoundedRect{ + MVMCoreUICheckBox *checkBox = [[self alloc] initWithRoundRect:true]; + checkBox.translatesAutoresizingMaskIntoConstraints = NO; + return checkBox ; +} + ++ (instancetype)mfCheckBoxWithCheckedColor:(UIColor *)checkedColor unCheckColor:(UIColor *)unCheckedColor text:(NSString *)text { + MVMCoreUICheckBox *checkBox = [[self alloc] initWithCheckedColor:checkedColor unCheckColor:unCheckedColor text:text]; + checkBox.translatesAutoresizingMaskIntoConstraints = NO; + return checkBox; +} + ++ (instancetype)mfCheckBoxWithCheckedColor:(UIColor *)checkedColor unCheckColor:(UIColor *)unCheckedColor atributedText:(NSAttributedString *)attributedText { + MVMCoreUICheckBox *checkBox = [[self alloc] initWithCheckedColor:checkedColor unCheckColor:unCheckedColor attributedText:attributedText]; + checkBox.translatesAutoresizingMaskIntoConstraints = NO; + return checkBox; +} + +#pragma mark - inits + +- (instancetype)initWithCheckedColor:(UIColor *)checkedColor unCheckColor:(UIColor *)unCheckedColor text:(NSString *)text { + if (self = [super init]) { + [self setupWithCheckedColor:checkedColor unCheckColor:unCheckedColor text:text]; + [self addAccessibleProperties]; + } + return self; +} + +- (instancetype)initWithCheckedColor:(UIColor *)checkedColor unCheckColor:(UIColor *)unCheckedColor attributedText:(NSAttributedString *)attributedText { + if (self = [super init]) { + [self setupWithCheckedColor:checkedColor unCheckColor:unCheckedColor text:nil]; + self.descriptionAttributedText = attributedText; + [self addAccessibleProperties]; + } + return self; +} + +- (nullable instancetype)initWithCheckMarkView:(nullable MVMCoreUICheckMarkView *)checkMarkView checkedColor:(nullable UIColor *)checkedColor unCheckColor:(nullable UIColor *)unCheckedColor text:(nullable NSString *)text { + if (self = [super init]) { + self.checkMark = checkMarkView; + [self setupWithCheckedColor:checkedColor unCheckColor:unCheckedColor text:text]; + [self addAccessibleProperties]; + } + return self; +} + +- (nullable instancetype)initWithCheckMarkView:(nullable MVMCoreUICheckMarkView *)checkMarkView checkedColor:(nullable UIColor *)checkedColor unCheckColor:(nullable UIColor *)unCheckedColor attributedText:(nullable NSAttributedString *)attributedText { + if (self = [super init]) { + self.checkMark = checkMarkView; + [self setupWithCheckedColor:checkedColor unCheckColor:unCheckedColor text:nil]; + self.descriptionAttributedText = attributedText; + [self addAccessibleProperties]; + } + return self; +} + +- (instancetype)initWithRoundRect:(BOOL)isRoundRect { + self = [super init]; + if (self) { + self.isRoundRectCheckMark = isRoundRect; + [self setupWithCheckedColor:[UIColor whiteColor] unCheckColor:[UIColor whiteColor] text:nil]; + [self addAccessibleProperties]; + [self setCheckMarkLayer]; + } + return self; +} + +//default inits +- (instancetype)initWithCoder:(NSCoder *)coder { + self = [super initWithCoder:coder]; + if (self) { + [self setupWithCheckedColor:[UIColor whiteColor] unCheckColor:[UIColor whiteColor] text:nil]; + [self addAccessibleProperties]; + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + [self setupWithCheckedColor:[UIColor whiteColor] unCheckColor:[UIColor whiteColor] text:nil]; + [self addAccessibleProperties]; + } + return self; +} + +- (void)awakeFromNib { + [super awakeFromNib]; + [self setupWithCheckedColor:[UIColor whiteColor] unCheckColor:[UIColor whiteColor] text:nil]; +} + +#pragma mark - set up + +- (void)setupView { + + UIView *containterView = [MVMCoreUICommonViewsUtility commonView]; + containterView.userInteractionEnabled = NO; + if (!self.sizeObject) { + self.sizeObject = [MFSizeObject sizeObjectWithStandardSize:CheckBoxHeightWidth standardiPadPortraitSize:CheckBoxHeightWidth+6]; + } + + //checked circle + if (!self.checkedSquare) { + UIView *checkedSquare = [MVMCoreUICommonViewsUtility commonView]; + checkedSquare.backgroundColor = [UIColor whiteColor]; + [containterView addSubview:checkedSquare]; + CGFloat size = [self.sizeObject getValueBasedOnApplicationWidth]; + NSDictionary *constraints = [NSLayoutConstraint constraintPinView:checkedSquare heightConstraint:YES heightConstant:size widthConstraint:YES widthConstant:size]; + self.checkboxWidth = constraints[ConstraintWidth]; + self.checkboxHeight = constraints[ConstraintHeight]; + [NSLayoutConstraint constraintPinSubview:checkedSquare pinTop:YES pinBottom:YES pinLeft:YES pinRight:NO]; + + self.checkboxRightPinConstraint = [checkedSquare.trailingAnchor constraintEqualToAnchor:containterView.trailingAnchor]; + + [NSLayoutConstraint constraintPinSubview:checkedSquare pinCenterX:NO pinCenterY:YES]; + self.checkedSquare = checkedSquare; + [self setCheckBoxBorder:[UIColor blackColor]]; + } + + //check mark + if (!self.checkMark) { + MVMCoreUICheckMarkView *checkMark = [[MVMCoreUICheckMarkView alloc] initWithFrame:self.frame]; + checkMark.lineWidth = 2.0; + self.checkMark = checkMark; + self.checkMark.translatesAutoresizingMaskIntoConstraints = NO; + [self.checkedSquare addSubview:self.checkMark]; + [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]; + } + + //label + if (!self.descriptionLabel) { + MFLabel *descriptionLabel = [MFLabel commonLabelB2:YES]; + [containterView addSubview:descriptionLabel]; + [NSLayoutConstraint constraintPinSubview:descriptionLabel pinCenterX:NO pinCenterY:YES]; + [NSLayoutConstraint constraintPinSubview:descriptionLabel pinTop:NO pinBottom:NO pinLeft:NO pinRight:YES]; + + self.descriptionLabelLeadingConstraint = [NSLayoutConstraint constraintWithItem:descriptionLabel attribute:NSLayoutAttributeLeading relatedBy:NSLayoutRelationEqual toItem:self.checkedSquare attribute:NSLayoutAttributeTrailing multiplier:1 constant:11]; + self.descriptionLabelLeadingConstraint.active = YES; + + self.descriptionLabelLeadingConstraint.active = YES; + self.descriptionLabel = descriptionLabel; + [self setSelected:NO]; + } + + if (!self.containerView) { + [self addSubview:containterView]; + self.containerView = containterView; + [NSLayoutConstraint constraintPinSubviewToSuperview:containterView]; + } +} + +- (void)setupWithCheckedColor:(UIColor *)checkedColor unCheckColor:(UIColor *)unCheckedColor text:(NSString *)text { + [self setupView]; + if (checkedColor) { + self.checkedColor = checkedColor; + } + if (unCheckedColor) { + self.unCheckedColor = unCheckedColor; + } + [self setDescriptionText:text]; +} + +- (void)updateView:(CGFloat)size { + [MVMCoreDispatchUtility performBlockOnMainThread:^{ + [self.descriptionLabel updateView:size]; + if ([self.checkMark respondsToSelector:@selector(updateView:)]) { + CGFloat width = [self.sizeObject getValueBasedOnSize:size]; + self.checkboxWidth.constant = width; + self.checkboxHeight.constant = width; + [self.checkMark updateView:size]; + } + }]; +} + +- (void)setCheckMarkLayer { + self.checkedSquare.layer.cornerRadius = self.isRoundRectCheckMark ? 5.0f : 0; +} + +#pragma mark - XIB Helpers + +- (instancetype)awakeAfterUsingCoder:(NSCoder *)aDecoder { + if ([self subviews].count == 0) { + return [MVMCoreUICheckBox mfCheckBox]; + } else { + return self; + } +} + +#pragma mark - control methods + +- (void)setSelected:(BOOL)selected { + [self setSelected:selected animated:YES]; +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [self addAccessibilityLabel:selected]; + + self.isSelected = selected; + if (self.switchSelected) { + self.switchSelected(selected); + } + if (selected) { + [UIView animateWithDuration:0.2 delay:0.1 options:UIViewAnimationOptionCurveEaseOut animations:^{ + self.checkedSquare.backgroundColor = self.checkedColor; + } completion:nil]; + [self.checkMark updateCheckSelected:YES animated:animated]; + } else { + [UIView animateWithDuration:0.2 delay:0.1 options:UIViewAnimationOptionCurveEaseOut animations:^{ + self.checkedSquare.backgroundColor = self.unCheckedColor; + } completion:nil]; + [self.checkMark updateCheckSelected:NO animated:animated]; + } +} + +- (void)setColor:(nullable UIColor *)color forState:(UIControlState)state { + if (color) { + switch (state) { + case UIControlStateNormal: + self.unCheckedColor = color; + break; + case UIControlStateSelected: + self.checkedColor = color; + break; + default: + break; + } + } +} + +#pragma mark - ui control subclass + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + if ([self touchIsOutside:[touches anyObject]]) { + [self sendActionsForControlEvents:UIControlEventTouchUpOutside]; + } else { + [self setSelected:!self.isSelected]; + [self sendActionsForControlEvents:UIControlEventTouchUpInside]; + } +} + +- (BOOL)touchIsOutside:(UITouch *)touch { + CGPoint endLocation = [touch locationInView:self]; + CGFloat x = endLocation.x; + CGFloat y = endLocation.y; + CGFloat widthLimit = self.frame.size.width + FaultTolerance; + CGFloat heightLimt = self.frame.size.height + FaultTolerance; + if (x < -FaultTolerance || y < -FaultTolerance || x > widthLimit || y > heightLimt) { + return YES; + } else { + return NO; + } +} + +#pragma mark - setter + +- (void)setDescriptionAttributedText:(NSAttributedString *)descriptionAttributedText { + self.descriptionLabel.text = nil; + self.descriptionLabel.attributedText = descriptionAttributedText; + [self setValueForAccessibilityText:[descriptionAttributedText string]]; +} + +- (void)setDescriptionText:(NSString *)descriptionText { + self.descriptionLabel.attributedText = nil; + self.descriptionLabel.text = descriptionText; + [self setValueForAccessibilityText:descriptionText]; +} + +#pragma mark - helper + +- (void)enable:(BOOL)enable { + self.userInteractionEnabled = enable; + //BR design change + if (!self.checkMarkLineColor) { + self.checkMarkLineColor = self.checkMark.lineColor; + } + + if (enable) { + self.checkedSquare.layer.borderColor = self.checkedBoxBorderColor.CGColor; + self.checkMark.lineColor = self.checkMarkLineColor; + self.descriptionLabel.alpha = 1.0; + } else { + self.checkedSquare.layer.borderColor = [UIColor mfSilver].CGColor; + self.checkMark.lineColor = [UIColor mfSilver]; + self.descriptionLabel.alpha = DisableOppacity; + } +} + +- (void)setCheckBoxBorder:(UIColor *)color { + self.checkedSquare.layer.borderWidth = 1; + self.checkedSquare.layer.borderColor = color.CGColor; + //BR design + self.checkedBoxBorderColor = color; +} + +#pragma mark - Accessibility +- (BOOL)isAccessibilityElement { + return YES; +} + +- (void)setValueForAccessibilityText:(nullable NSString *)text { + self.accessibilityText = text; + [self addAccessibilityLabel:self.isSelected]; +} +- (void)addAccessibleProperties { + self.accessibilityTraits = UIAccessibilityTraitNone; + self.accessibilityHint = [MVMCoreUIUtility hardcodedStringWithKey:@"checkbox_action_hint"]; +} + +- (void)addAccessibilityLabel:(BOOL)selected { + NSString *state = selected?[MVMCoreUIUtility hardcodedStringWithKey:@"checkbox_checked_state"]:[MVMCoreUIUtility hardcodedStringWithKey:@"checkbox_unchecked_state"]; + NSString *description = self.accessibilityText.length ? self.accessibilityText:@""; + self.accessibilityLabel = [NSString stringWithFormat:[MVMCoreUIUtility hardcodedStringWithKey:@"checkbox_desc_state"],description,state]; +} + +- (void)hideDescriptionLabelAndPinCheckboxToRight { + self.descriptionLabel.hidden = YES; + self.checkboxRightPinConstraint.active = YES; + self.descriptionLabelLeadingConstraint.constant = 0; +} + +@end diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUICheckMarkView.h b/MVMCoreUI/Atoms/Views/MVMCoreUICheckMarkView.h new file mode 100644 index 00000000..694fc72b --- /dev/null +++ b/MVMCoreUI/Atoms/Views/MVMCoreUICheckMarkView.h @@ -0,0 +1,17 @@ +// +// MVMCoreUICheckMarkView.h +// mobilefirst +// +// Created by Shreyas Seshamani on 2/17/16. +// Copyright © 2016 Verizon Wireless. All rights reserved. +// + +#import +#import + +@interface MVMCoreUICheckMarkView : MFView + +@property (nonatomic) CGFloat lineWidth; +@property (nonatomic, strong) UIColor *lineColor; +- (void)updateCheckSelected:(BOOL)selected animated:(BOOL)animated; +@end diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUICheckMarkView.m b/MVMCoreUI/Atoms/Views/MVMCoreUICheckMarkView.m new file mode 100644 index 00000000..6889870b --- /dev/null +++ b/MVMCoreUI/Atoms/Views/MVMCoreUICheckMarkView.m @@ -0,0 +1,133 @@ +// +// MVMCoreUICheckMarkView.m +// mobilefirst +// +// Created by Shreyas Seshamani on 2/17/16. +// Copyright © 2016 Verizon Wireless. All rights reserved. +// + +#import "MVMCoreUICheckMarkView.h" +#import +#import + +@interface MVMCoreUICheckMarkView () + +@property (nonatomic) float drawPercentage; +@property (strong, nonatomic) NSTimer * animationTimer; +@property (strong, nonatomic) CAShapeLayer *checkLayer; +@property (nonatomic) BOOL selected; +@end + +@implementation MVMCoreUICheckMarkView + +//Offsets based on the 124x124 example checkmark +const float startXOffset = (42.0/124.0); +const float startYOffset = (66.0/124.0); +const float pivotXOffset = (58.0/124.0); +const float pivotYOffset = (80.0/124.0); +const float endXOffset = (83.0/124.0); +const float endYOffset = (46.0/124.0); +const float pivotPercentage = 0.34; +const float endPercentage = 1.0 - pivotPercentage; +const float animationInterval = 0.01; + +- (void)setupView { + [super setupView]; + self.backgroundColor = [UIColor clearColor]; + self.drawPercentage = 1.0; + _lineColor = [UIColor blackColor]; + _lineWidth = 1.0; +} + +- (void)updateView:(CGFloat)size { + [super updateView:size]; +} + +- (void)drawCheck { + if (!self.checkLayer) { + [self layoutIfNeeded]; + UIBezierPath *path = [UIBezierPath bezierPath]; + [path moveToPoint:CGPointMake(self.lineWidth/2, self.bounds.size.height*.55)]; + [path addLineToPoint:CGPointMake(self.bounds.size.width*.45, self.bounds.size.height*.85)]; + [path addLineToPoint:CGPointMake(self.bounds.size.width - self.lineWidth/2, self.lineWidth/2)]; + + self.checkLayer = [[CAShapeLayer alloc] init]; + self.checkLayer.frame = self.bounds; + [self.layer addSublayer:self.checkLayer]; + self.checkLayer.strokeColor = self.lineColor.CGColor ?: [UIColor blackColor].CGColor; + self.checkLayer.fillColor = [UIColor clearColor].CGColor; + self.checkLayer.path = path.CGPath; + self.checkLayer.lineWidth = self.lineWidth; + + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + self.checkLayer.strokeEnd = 0.0; + [CATransaction commit]; + } +} + +- (void)updateCheckSelected:(BOOL)selected animated:(BOOL)animated { + [MVMCoreDispatchUtility performBlockOnMainThread:^{ + self.selected = selected; + + // animate this bar + [self drawCheck]; + + CAShapeLayer *layer; + if (self.checkLayer.presentationLayer && animated) { + layer = self.checkLayer.presentationLayer; + } else { + layer = self.checkLayer; + } + + if (animated) { + CABasicAnimation *animateStrokeEnd = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + animateStrokeEnd.fillMode = kCAFillModeBoth; + animateStrokeEnd.removedOnCompletion = NO; + animateStrokeEnd.duration = .3; + + animateStrokeEnd.fromValue = [NSNumber numberWithFloat:[layer strokeEnd]]; + if (selected) { + animateStrokeEnd.toValue = [NSNumber numberWithFloat:1]; + } else { + animateStrokeEnd.toValue = [NSNumber numberWithFloat:0]; + } + + animateStrokeEnd.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; + [layer addAnimation:animateStrokeEnd forKey:@"strokeEndAnimation"]; + } else { + [layer removeAllAnimations]; + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + if (selected) { + layer.strokeEnd = 1.0; + } else { + layer.strokeEnd = 0.0; + } + [CATransaction commit]; + } + }]; +} + +- (void)setLineWidth:(CGFloat)lineWidth { + _lineWidth = lineWidth; + if (self.checkLayer) { + [self.checkLayer removeFromSuperlayer]; + self.checkLayer = nil; + [self updateCheckSelected:self.selected animated:NO]; + } +} + +- (void)setLineColor:(UIColor *)lineColor { + _lineColor = lineColor; + if (self.checkLayer) { + self.checkLayer.strokeColor = lineColor.CGColor; + [self updateCheckSelected:self.selected animated:NO]; + } +} + +- (void)layoutSubviews { + [self drawCheck]; +} + +@end diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.h b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.h new file mode 100644 index 00000000..8c42f5e5 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.h @@ -0,0 +1,34 @@ +// +// MVMSwitch.h +// myverizon +// +// Created by Tianhang Yang on 12/1/15. +// Copyright © 2015 Verizon Wireless. All rights reserved. +// + + +#import +@import MVMCore.MVMCoreViewProtocol; +typedef void(^ValueChangeBlock)(void); + +@interface MVMCoreUISwitch : UIControl + +@property (assign, nonatomic, getter=isOn) BOOL on; +@property (nullable, strong, nonatomic) UIColor *onTintColor; +@property (nullable, strong, nonatomic) UIColor *offTintColor; + +@property (nullable, strong, nonatomic) UIColor *onKnobTintColor; +@property (nullable, strong, nonatomic) UIColor *offKnobTintColor; + +@property (nonatomic) BOOL shouldTouchToSwitch; +@property (nullable, copy, nonatomic) ValueChangeBlock valueChangedBlock; + ++ (nullable instancetype)mvmSwitchDefault; ++ (nullable instancetype)mvmSwitchDefaultWithValueChangeBlock:(nullable ValueChangeBlock)block; + +- (void)setState:(BOOL)state animated:(BOOL)animated; + +// Sets the state without triggering the value changed block. +- (void)setState:(BOOL)stateWithoutBlock withoutBlockAnimated:(BOOL)animated; + +@end diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m new file mode 100644 index 00000000..9b9e0b96 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/MVMCoreUISwitch.m @@ -0,0 +1,364 @@ +// +// MVMSwitch.m +// myverizon +// +// Created by Tianhang Yang on 12/1/15. +// Copyright © 2015 Verizon Wireless. All rights reserved. +// + +#import "MVMCoreUISwitch.h" +@import MVMCore.NSDictionary_MFConvenience; +#import +#import +#import +#import +#import +#import + +const CGFloat SwitchWidth = 42; +const CGFloat SwitchHeight = 22; +const CGFloat SwitchKnobWidth = 20; +const CGFloat SwitchKnobHeight = 20; +const CGFloat SwitchShakeIntensity = 2; + +@interface MVMCoreUISwitch () + +@property (weak, nonatomic) UIView *baseView; +@property (weak, nonatomic) UIView *knobView; +@property (strong, nonatomic) NSLayoutConstraint *knobLeftConstraint; +@property (strong, nonatomic) NSLayoutConstraint *knobRightConstraint; +@property (strong, nonatomic) NSLayoutConstraint *knobHeightConstraint; +@property (strong, nonatomic) NSLayoutConstraint *knobWidthConstraint; + +@property (weak, nonatomic) NSLayoutConstraint *height; +@property (weak, nonatomic) NSLayoutConstraint *width; + +@property (assign, nonatomic) BOOL valueShouldChange; + +@property (nonatomic) BOOL canChangeValue; + +@end + +@implementation MVMCoreUISwitch + +- (void)updateView:(CGFloat)size { + self.height.constant = [MVMCoreUISwitch getSwitchHeight]; + self.width.constant = [MVMCoreUISwitch getSwitchWidth]; + self.baseView.layer.cornerRadius = [MVMCoreUISwitch getSwitchHeight]/2.f; + self.knobView.layer.cornerRadius = [MVMCoreUISwitch getSwitchKnobHeight]*0.5; + self.knobHeightConstraint.constant = [MVMCoreUISwitch getSwitchKnobHeight]; + self.knobWidthConstraint.constant = [MVMCoreUISwitch getSwitchKnobWidth]; +} + +- (void)setupView { + self.onTintColor = [UIColor mfSwitchOnTintColor]; + self.offTintColor = [UIColor mfSwitchOffTintColor]; + self.canChangeValue = YES; + self.shouldTouchToSwitch = YES; + [self setUpViewWithState:self.on]; + self.accessibilityLabel = [MVMCoreUIUtility hardcodedStringWithKey:@"MVMCoreUISwitch_buttonlabel"]; +} + +- (instancetype)initWithCoder:(NSCoder *)coder { + if ([super initWithCoder:coder]) { + [self setupView]; + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame { + if ([super initWithFrame:frame]) { + [self setupView]; + } + return self; +} + +- (instancetype)init { + if ([super init]) { + [self setupView]; + } + return self; +} + ++ (instancetype)mvmSwitchDefault { + MVMCoreUISwitch *mySwitch = [[self alloc] initWithFrame:CGRectZero]; + mySwitch.translatesAutoresizingMaskIntoConstraints = NO; + return mySwitch; +} + ++ (nullable instancetype)mvmSwitchDefaultWithValueChangeBlock:(nullable ValueChangeBlock)block { + MVMCoreUISwitch *mySwitch = [[self alloc] initWithFrame:CGRectZero]; + mySwitch.valueChangedBlock = block; + return mySwitch; +} + +- (void)setUpViewWithState:(BOOL)on { + if (!self.baseView) { + self.userInteractionEnabled = YES; + self.valueShouldChange = YES; + + UIView *baseView = [MVMCoreUICommonViewsUtility commonView]; + [self addSubview:baseView]; + [NSLayoutConstraint constraintPinSubviewToSuperview:baseView]; + NSDictionary *constraints = [NSLayoutConstraint constraintPinView:baseView heightConstraint:YES heightConstant:[MVMCoreUISwitch getSwitchHeight] widthConstraint:YES widthConstant:[MVMCoreUISwitch getSwitchWidth]]; + self.height = [constraints objectForKey:ConstraintHeight ofType:[NSLayoutConstraint class]]; + self.width = [constraints objectForKey:ConstraintWidth ofType:[NSLayoutConstraint class]]; + baseView.layer.cornerRadius = [MVMCoreUISwitch getSwitchHeight]/2.f; + + self.onKnobTintColor = [UIColor whiteColor]; + self.offKnobTintColor = [UIColor whiteColor]; + + UIView *knobView = [MVMCoreUICommonViewsUtility commonView]; + knobView.backgroundColor = [UIColor whiteColor]; + knobView.layer.cornerRadius = [MVMCoreUISwitch getSwitchKnobHeight]*0.5; + [baseView addSubview:knobView]; + NSDictionary *heightWidth = [NSLayoutConstraint constraintPinView:knobView heightConstraint:YES heightConstant:[MVMCoreUISwitch getSwitchKnobHeight] widthConstraint:YES widthConstant:[MVMCoreUISwitch getSwitchKnobWidth]]; + NSLayoutConstraint *height = [heightWidth objectForKey:ConstraintHeight ofType:[NSLayoutConstraint class]]; + NSLayoutConstraint *width = [heightWidth objectForKey:ConstraintWidth ofType:[NSLayoutConstraint class]]; + self.knobHeightConstraint = height; + self.knobWidthConstraint = width; + NSDictionary *leadingTrailingDic = [NSLayoutConstraint constraintPinSubview:knobView pinTop:NO topConstant:0 pinBottom:NO bottomConstant:0 pinLeft:YES leftConstant:1 pinRight:YES rightConstant:1]; + NSLayoutConstraint *left = [leadingTrailingDic objectForKey:ConstraintLeading ofType:[NSLayoutConstraint class]]; + NSLayoutConstraint *right = [leadingTrailingDic objectForKey:ConstraintTrailing ofType:[NSLayoutConstraint class]]; + [NSLayoutConstraint constraintPinSubview:knobView pinCenterX:NO centerXConstant:0 pinCenterY:YES centerYConstant:0]; + right.constant = 15; + self.knobLeftConstraint = left; + self.knobRightConstraint = right; + [baseView bringSubviewToFront:knobView]; + + self.baseView = baseView; + self.knobView = knobView; + + self.baseView.userInteractionEnabled = NO; + self.knobView.userInteractionEnabled = NO; + self.shouldTouchToSwitch = NO; + [self setState:on animated:NO]; + self.shouldTouchToSwitch = YES; + } +} + +#pragma mark - UIResponder overide + +- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { + [self knobEnlargeAnimation]; + [self sendActionsForControlEvents:UIControlEventTouchDown]; +} + +- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event { + if (self.shouldTouchToSwitch) { + if (self.valueShouldChange) { + [self changeValue]; + } + } + [self sendActionsForControlEvents:UIControlEventTouchUpInside]; + [self knobMoveAnitmationToOn:self.isOn]; + [self knobShakeAnitmationToOn:self.isOn]; + [self knobReformAnimation:YES]; + self.valueShouldChange = YES; +} + +- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { + if (self.shouldTouchToSwitch) { + if ([self touchMovesToLeft:touches]) { + [self knobMoveAnitmationToOn:NO]; + [self knobShakeAnitmationToOn:NO]; + [self knobReformAnimation :YES]; + + } else { + [self knobMoveAnitmationToOn:YES]; + [self knobShakeAnitmationToOn:YES]; + [self knobReformAnimation :YES]; + } + } + if ([self touchIsOutSide:touches]){ + [self sendActionsForControlEvents:UIControlEventTouchDragOutside]; + if (!self.shouldTouchToSwitch) { + [self knobReformAnimation:YES]; + } + } else { + [self sendActionsForControlEvents:UIControlEventTouchDragInside]; + } +} + +- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event { + if (self.shouldTouchToSwitch) { + [self knobReformAnimation :YES]; + self.canChangeValue = YES; + } + [self sendActionsForControlEvents:UIControlEventTouchCancel]; +} + +#pragma mark - animation + +- (void)knobEnlargeAnimation { + [UIView animateWithDuration:0.1 animations:^{ + self.knobWidthConstraint.constant += PaddingOne; + [self layoutIfNeeded]; + }]; +} + +- (void)knobReformAnimation :(BOOL)animated { + if(animated) { + [UIView animateWithDuration:0.1 animations:^{ + self.knobWidthConstraint.constant = [MVMCoreUISwitch getSwitchKnobWidth]; + [self layoutIfNeeded]; + } completion:^(BOOL finished) { + }]; + } else { + self.knobWidthConstraint.constant = [MVMCoreUISwitch getSwitchKnobWidth]; + [self layoutIfNeeded]; + } +} + +- (void)knobMoveAnitmationToOn:(BOOL)toOn { + [UIView animateWithDuration:0.1 animations:^{ + if (toOn) { + self.knobLeftConstraint.priority = 1; + self.knobRightConstraint.priority = 999; + self.knobRightConstraint.constant = 1; + } else { + self.knobLeftConstraint.priority = 999; + self.knobRightConstraint.priority = 1; + self.knobLeftConstraint.constant = 1; + } + [self setBaseColorToOn:toOn animated:YES]; + self.knobWidthConstraint.constant = [MVMCoreUISwitch getSwitchKnobWidth]+PaddingOne; + self.valueShouldChange = (toOn != self.on); + [self layoutIfNeeded]; + }]; +} + +- (void)setBaseColorToOn:(BOOL)toOn animated:(BOOL)animated { + if (animated) { + [UIView beginAnimations:nil context:nil]; + [UIView setAnimationDuration:0.2]; + [UIView setAnimationCurve:UIViewAnimationCurveEaseIn]; + if (toOn) { + self.knobView.backgroundColor = self.onKnobTintColor; + [self.baseView setBackgroundColor:self.onTintColor]; + } else { + self.knobView.backgroundColor = self.offKnobTintColor; + [self.baseView setBackgroundColor:self.offTintColor]; + } + [UIView commitAnimations]; + } else if (self.on) { + self.knobView.backgroundColor = self.onKnobTintColor; + [self.baseView setBackgroundColor:self.onTintColor]; + } else { + self.knobView.backgroundColor = self.offKnobTintColor; + [self.baseView setBackgroundColor:self.offTintColor]; + } +} + +//used after knob moving to match the behavior of default uiswitch +- (void)knobShakeAnitmationToOn:(BOOL)toOn { + [UIView animateWithDuration:0.1 delay:0.1 options:UIViewAnimationOptionCurveEaseIn animations:^{ + if (toOn) { + self.knobRightConstraint.constant = SwitchShakeIntensity; + } else { + self.knobLeftConstraint.constant = SwitchShakeIntensity; + } + [self layoutIfNeeded]; + } completion:^(BOOL finished) { + }]; + [UIView animateWithDuration:0.2 delay:0.1 options:0 animations:^{ + if (toOn) { + self.knobRightConstraint.constant = 1; + } else { + self.knobLeftConstraint.constant = 1; + } + [self layoutIfNeeded]; + } completion:^(BOOL finished) { + self.valueShouldChange = YES; + }]; +} + +#pragma mark - switch logic + +- (void)setState:(BOOL)state animated:(BOOL)animated { + [self setState:state withoutBlockAnimated:animated]; + if (self.valueChangedBlock) { + self.valueChangedBlock(); + } +} + +- (void)setState:(BOOL)state withoutBlockAnimated:(BOOL)animated { + self.on = state; + if (!self.shouldTouchToSwitch) { + [self knobEnlargeAnimation]; + [self knobMoveAnitmationToOn:self.on]; + [self knobShakeAnitmationToOn:self.on]; + } + if (self.on) { + self.knobLeftConstraint.priority = 1; + self.knobRightConstraint.priority = 999; + self.knobRightConstraint.constant = 1; + } + else { + self.knobRightConstraint.priority = 1; + self.knobLeftConstraint.priority = 999; + self.knobLeftConstraint.constant = 1; + } + + [self setBaseColorToOn:self.on animated:animated]; + [self knobReformAnimation:animated]; + self.accessibilityValue = state ? [MVMCoreUIUtility hardcodedStringWithKey:@"AccOn"] : [MVMCoreUIUtility hardcodedStringWithKey:@"AccOff"]; + [self setNeedsLayout]; + [self layoutIfNeeded]; +} + + +- (BOOL)changeValue{ + self.on^=YES; + self.shouldTouchToSwitch = NO; + [self setState:self.on animated:YES]; + self.shouldTouchToSwitch = YES; + [self sendActionsForControlEvents:UIControlEventValueChanged]; + return self.on; +} + +#pragma mark - helper + +- (BOOL)touchIsOutSide:(NSSet *)touches { + CGPoint location = [[touches anyObject] locationInView:self]; + float x = location.x; + float y = location.y; + return (x<0 || x >self.frame.size.width || y <0 || y > self.frame.size.height); +} + +- (BOOL)touchMovesToLeft:(NSSet *)touches { + CGPoint location = [[touches anyObject] locationInView:self]; + float x = location.x; + return (x< self.frame.size.width/2.f); +} + ++ (CGFloat)getSwitchWidth { + return [[MFSizeObject sizeObjectWithStandardSize:SwitchWidth standardiPadPortraitSize:SwitchWidth * 1.5] getValueBasedOnApplicationWidth]; +} + ++ (CGFloat)getSwitchHeight { + return [[MFSizeObject sizeObjectWithStandardSize:SwitchHeight standardiPadPortraitSize:SwitchHeight * 1.5] getValueBasedOnApplicationWidth]; +} + ++ (CGFloat)getSwitchKnobWidth { + return [[MFSizeObject sizeObjectWithStandardSize:SwitchKnobWidth standardiPadPortraitSize:SwitchKnobWidth * 1.5] getValueBasedOnApplicationWidth]; +} + ++ (CGFloat)getSwitchKnobHeight { + return [[MFSizeObject sizeObjectWithStandardSize:SwitchKnobHeight standardiPadPortraitSize:SwitchKnobHeight * 1.5] getValueBasedOnApplicationWidth]; +} + +#pragma mark - Accessibility +- (BOOL)isAccessibilityElement{ + return YES; +} + +- (UIAccessibilityTraits)accessibilityTraits { + return UIAccessibilityTraitButton; +} + +- (NSString *)accessibilityHint { + return [MVMCoreUIUtility hardcodedStringWithKey:@"AccToggleHint"]; +} + +@end diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUITextFieldView.h b/MVMCoreUI/Atoms/Views/MVMCoreUITextFieldView.h new file mode 100644 index 00000000..757b937e --- /dev/null +++ b/MVMCoreUI/Atoms/Views/MVMCoreUITextFieldView.h @@ -0,0 +1,23 @@ +// +// MVMCoreUITextFieldView.h +// mobilefirst +// +// Created by Seshamani, Shreyas on 6/24/16. +// Copyright © 2016 Verizon Wireless. All rights reserved. +// + +#import +#import + +@interface MVMCoreUITextFieldView : ViewConstrainingView + +@property (nullable, weak, nonatomic) MFTextField *mvmTextField; + ++ (nullable instancetype)createWithDelegate:(nullable id )delegate; + +// Change the alignment of the label +- (void)alignLeft; +- (void)alignCenter; +- (void)alignRight; + +@end diff --git a/MVMCoreUI/Atoms/Views/MVMCoreUITextFieldView.m b/MVMCoreUI/Atoms/Views/MVMCoreUITextFieldView.m new file mode 100644 index 00000000..4e3b2f72 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/MVMCoreUITextFieldView.m @@ -0,0 +1,107 @@ +// +// MVMCoreUITextFieldView.m +// mobilefirst +// +// Created by Seshamani, Shreyas on 6/24/16. +// Copyright © 2016 Verizon Wireless. All rights reserved. +// + +#import "MVMCoreUITextFieldView.h" +#import "NSLayoutConstraint+MFConvenience.h" + +@interface MVMCoreUITextFieldView () +@property (weak, nonatomic) NSLayoutConstraint *alignCenterPin; +@property (weak, nonatomic) NSLayoutConstraint *alignCenterLeftPin; +@property (weak, nonatomic) NSLayoutConstraint *alignCenterRightPin; +@end + +@implementation MVMCoreUITextFieldView + ++ (instancetype)createWithDelegate:(id )delegate { + MVMCoreUITextFieldView *textFieldView = [[MVMCoreUITextFieldView alloc] init]; + textFieldView.mvmTextField.mfTextFieldDelegate = delegate; + textFieldView.mvmTextField.uiTextFieldDelegate = delegate; + return textFieldView; +} + +- (void)setupView { + [super setupView]; + if (!self.mvmTextField) { + MFTextField *mfTextField = [MFTextField mfTextField]; + mfTextField.translatesAutoresizingMaskIntoConstraints = NO; + [self addSubview:mfTextField]; + self.mvmTextField = mfTextField; + + NSLayoutConstraint *leftPin = [NSLayoutConstraint constraintWithItem:mfTextField attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0]; + self.leftPin = leftPin; + leftPin.active = YES; + + NSLayoutConstraint *topPin = [NSLayoutConstraint constraintWithItem:mfTextField attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]; + self.topPin = topPin; + topPin.active = YES; + + NSLayoutConstraint *bottomPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:mfTextField attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0]; + self.bottomPin = bottomPin; + bottomPin.active = YES; + + NSLayoutConstraint *rightPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:mfTextField attribute:NSLayoutAttributeRight multiplier:1.0 constant:0]; + self.rightPin = rightPin; + rightPin.active = YES; + + // Center alignments + NSLayoutConstraint *alignCenter = [NSLayoutConstraint constraintWithItem:mfTextField attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]; + self.alignCenterPin = alignCenter; + alignCenter.active = YES; + + NSLayoutConstraint *centerLeftPin = [NSLayoutConstraint constraintWithItem:mfTextField attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0]; + self.alignCenterLeftPin = centerLeftPin; + centerLeftPin.active = YES; + + NSLayoutConstraint *centerRightPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:mfTextField attribute:NSLayoutAttributeRight multiplier:1.0 constant:0]; + self.alignCenterRightPin = centerRightPin; + centerRightPin.active = YES; + + [self alignLeft]; + } +} + +- (void)alignLeft { + self.alignCenterPin.active = NO; + self.alignCenterLeftPin.active = NO; + self.alignCenterRightPin.active = NO; + self.leftPin.active = YES; + self.rightPin.active = YES; +} + +- (void)alignCenter { + self.alignCenterPin.active = YES; + self.alignCenterLeftPin.active = YES; + self.alignCenterRightPin.active = YES; + self.leftPin.active = NO; + self.rightPin.active = NO; +} + +- (void)alignRight { + self.alignCenterPin.active = NO; + self.alignCenterLeftPin.active = NO; + self.alignCenterRightPin.active = NO; + self.leftPin.active = YES; + self.rightPin.active = YES; +} + +- (void)setLeftPinConstant:(CGFloat)constant { + self.leftPin.constant = constant; + self.alignCenterLeftPin.constant = constant; +} + +- (void)setRightPinConstant:(CGFloat)constant { + self.rightPin.constant = constant; + self.alignCenterRightPin.constant = constant; +} + +- (void)resetConstraints { + [super resetConstraints]; + [self alignLeft]; +} + +@end diff --git a/MVMCoreUI/Atoms/Views/TextFieldView.h b/MVMCoreUI/Atoms/Views/TextFieldView.h deleted file mode 100644 index 5d87c301..00000000 --- a/MVMCoreUI/Atoms/Views/TextFieldView.h +++ /dev/null @@ -1,15 +0,0 @@ -// -// TextFieldView.h -// mobilefirst -// -// Created by Seshamani, Shreyas on 6/24/16. -// Copyright © 2016 Verizon Wireless. All rights reserved. -// - -#import - -@interface TextFieldView : ViewConstrainingView - -@property (nonatomic, weak, nullable) UITextField *textField; - -@end diff --git a/MVMCoreUI/Atoms/Views/TextFieldView.m b/MVMCoreUI/Atoms/Views/TextFieldView.m deleted file mode 100644 index a548b64d..00000000 --- a/MVMCoreUI/Atoms/Views/TextFieldView.m +++ /dev/null @@ -1,44 +0,0 @@ -// -// TextFieldView.m -// mobilefirst -// -// Created by Seshamani, Shreyas on 6/24/16. -// Copyright © 2016 Verizon Wireless. All rights reserved. -// - -#import "TextFieldView.h" - -@implementation TextFieldView - -- (void)setupView { - if (!self.textField) { - self.backgroundColor = [UIColor clearColor]; - - UITextField *textField = [[UITextField alloc]initWithFrame:CGRectZero]; - [self addSubview:textField]; - textField.translatesAutoresizingMaskIntoConstraints = NO; - self.textField = textField; - self.textField.backgroundColor = [UIColor whiteColor]; - - // Align left and right constants. - NSLayoutConstraint *leftPin = [NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0]; - self.leftPin = leftPin; - leftPin.active = YES; - - NSLayoutConstraint *topPin = [NSLayoutConstraint constraintWithItem:textField attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]; - topPin.priority = 999; - self.topPin = topPin; - topPin.active = YES; - - NSLayoutConstraint *bottomPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:textField attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0]; - self.bottomPin = bottomPin; - bottomPin.active = YES; - - NSLayoutConstraint *rightPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:textField attribute:NSLayoutAttributeRight multiplier:1.0 constant:0]; - rightPin.priority = 999; - self.rightPin = rightPin; - rightPin.active = YES; - } -} - -@end diff --git a/MVMCoreUI/BaseControllers/StackableViewController.h b/MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.h similarity index 75% rename from MVMCoreUI/BaseControllers/StackableViewController.h rename to MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.h index ceab058f..9e7d352e 100644 --- a/MVMCoreUI/BaseControllers/StackableViewController.h +++ b/MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.h @@ -1,15 +1,14 @@ // -// StackableViewController.h -// myverizon +// MVMCoreUIStackableViewController.h +// MVMCoreUI // -// Created by Scott Pfeil on 3/26/14. -// Copyright (c) 2014 Verizon Wireless. All rights reserved. +// Created by Scott Pfeil on 2/1/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. // -// This view controller is here to enable faster development of standard form screens. Put all ui objects that you want to be displayed in a top down order in an array and then call the generateFormWithUIArray. Any type can go in it. #import -@interface StackableViewController : ProgrammaticScrollViewController +@interface MVMCoreUIStackableViewController : ProgrammaticScrollViewController // An array of ui elements that will be spaced out on the screen top to bottom from index 0 to formUIArray.count. @property (nullable, strong, nonatomic) NSArray *formUIArray; @@ -17,12 +16,9 @@ // Generates the form view with the passed in form ui array. - (void)generateFormViewWithUIArray:(nullable NSArray *)formUIArray; - (void)generateFormView:(nullable UIView *)view withUIArrayForConstrainingViews:(nullable NSArray *)formUIArray; - -// Returns the spacing that should surround the passed in item. Subclass this to change spacing. -- (UIEdgeInsets)spaceAroundUIObject:(nullable id)object; -// When using constraining views in the form array, resets the space that should surround each element. -- (void)resetSpaceForFormArrayWithConstrainingViews; +// Returns the spacing that should surround the passed in item. Subclass this to change spacing. +- (UIEdgeInsets)spaceAroundUIObject:(nullable id)object size:(CGFloat)size; // Removes all the subviews in the form ui array. - (void)removeUIViews; @@ -31,8 +27,8 @@ + (void)removeUIViews:(nullable NSArray *)views; // Returns the standard space around ui objects. -+ (UIEdgeInsets)standardSpaceAroundUIObject; - ++ (UIEdgeInsets)standardSpaceAroundUIObjectForSize:(CGFloat)size; + // Consolidates generateFormViewWithUIArray and spaceArroundUIObject into one class object so other view controllers can take advantage of these functions. + (void)populateView:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock; + (void)populateViewHorizontally:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock; diff --git a/MVMCoreUI/BaseControllers/StackableViewController.m b/MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.m similarity index 83% rename from MVMCoreUI/BaseControllers/StackableViewController.m rename to MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.m index a1bc78d1..86f4ebfe 100644 --- a/MVMCoreUI/BaseControllers/StackableViewController.m +++ b/MVMCoreUI/BaseControllers/MVMCoreUIStackableViewController.m @@ -1,20 +1,30 @@ // -// StackableViewController.m -// myverizon +// MVMCoreUIMVMCoreUIStackableViewController.m +// MVMCoreUI // -// Created by Scott Pfeil on 3/26/14. -// Copyright (c) 2014 Verizon Wireless. All rights reserved. +// Created by Scott Pfeil on 2/1/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. // -#import "StackableViewController.h" +#import "MVMCoreUIStackableViewController.h" #import "MFStyler.h" #import "ViewConstrainingView.h" - -@interface StackableViewController () +#import "MVMCoreUIUtility.h" +@interface MVMCoreUIStackableViewController () @end -@implementation StackableViewController +@implementation MVMCoreUIStackableViewController + +- (void)updateViews { + [super updateViews]; + for (UIView *view in self.formUIArray) { + CGFloat size = CGRectGetWidth(self.view.bounds); + ViewConstrainingView *constrainingView = (ViewConstrainingView *)view.superview; + [constrainingView setPinConstantsWithInsets:[self spaceAroundUIObject:view size:size]]; + [constrainingView updateView:size]; + } +} - (void)newDataBuildScreen { [super newDataBuildScreen]; @@ -24,33 +34,31 @@ } - (void)generateFormViewWithUIArray:(nullable NSArray *)formUIArray { - self.formUIArray = formUIArray; - [StackableViewController populateView:self.contentView withUIArray:formUIArray withSpacingBlock:^UIEdgeInsets(id _Nullable object) { - return [self spaceAroundUIObject:object]; - }]; -} - -- (void)generateFormView:(nullable UIView *)view withUIArrayForConstrainingViews:(nullable NSArray *)formUIArray { - self.formUIArray = formUIArray; - [StackableViewController populateView:view withUIArrayForConstrainingViews:formUIArray withSpacingBlock:^UIEdgeInsets(id _Nullable object) { - return [self spaceAroundUIObject:object]; + [MVMCoreUIStackableViewController populateView:self.contentView withUIArray:formUIArray withSpacingBlock:^UIEdgeInsets(id _Nullable object) { + return [self spaceAroundUIObject:object size:[MVMCoreUIUtility getWidth]]; }]; } -- (UIEdgeInsets)spaceAroundUIObject:(nullable id)object { - - UIEdgeInsets insets = [StackableViewController standardSpaceAroundUIObject]; +- (void)generateFormView:(nullable UIView *)view withUIArrayForConstrainingViews:(nullable NSArray *)formUIArray { + self.formUIArray = formUIArray; + [MVMCoreUIStackableViewController populateView:view withUIArrayForConstrainingViews:formUIArray withSpacingBlock:^UIEdgeInsets(id _Nullable object) { + return [self spaceAroundUIObject:object size:[MVMCoreUIUtility getWidth]]; + }]; +} + +- (UIEdgeInsets)spaceAroundUIObject:(nullable id)object size:(CGFloat)size { + UIEdgeInsets insets = [MVMCoreUIStackableViewController standardSpaceAroundUIObjectForSize:size]; if (object == [self.formUIArray lastObject]) { // The last object should have space from the bottom - insets.bottom = [MFStyler defaultVerticalPaddingForApplicationWidth]; + insets.bottom = [MFStyler defaultVerticalPaddingForSize:size]; } return insets; } - (void)removeUIViews { - [StackableViewController removeUIViews:self.formUIArray]; + [MVMCoreUIStackableViewController removeUIViews:self.formUIArray]; } + (void)removeUIViews:(nullable NSArray *)views { @@ -61,44 +69,34 @@ } + (void)populateView:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock { - if ([formUIArray count] > 0) { - for (UIView *subview in formUIArray) { [view addSubview:subview]; } - - [StackableViewController autoLayoutView:view withUIArray:formUIArray withSpacingBlock:spacingBlock]; + [MVMCoreUIStackableViewController autoLayoutView:view withUIArray:formUIArray withSpacingBlock:spacingBlock]; } } + (void)populateViewHorizontally:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock { - if ([formUIArray count] > 0) { - for (UIView *subview in formUIArray) { [view addSubview:subview]; } - - [StackableViewController autoLayoutViewHorizontally:view withUIArray:formUIArray withSpacingBlock:spacingBlock]; + [MVMCoreUIStackableViewController autoLayoutViewHorizontally:view withUIArray:formUIArray withSpacingBlock:spacingBlock]; } } - + + (void)populateView:(nonnull UIView *)view withUIArrayForConstrainingViews:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock { - if ([formUIArray count] > 0) { - for (UIView *subview in formUIArray) { ViewConstrainingView *constrainingView = [ViewConstrainingView viewConstrainingView:subview]; [view addSubview:constrainingView]; } - - [StackableViewController autoLayoutViewWithConstrainingViewsWithUIArray:formUIArray withSpacingBlock:spacingBlock]; + [MVMCoreUIStackableViewController autoLayoutViewWithConstrainingViewsWithUIArray:formUIArray withSpacingBlock:spacingBlock]; } } + (void)autoLayoutView:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray 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. @@ -127,7 +125,6 @@ } + (void)autoLayoutViewHorizontally:(nonnull UIView *)view withUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock { - if ([formUIArray count] > 0) { // Adds the first object to the view and pins it to the top and left of the content view. @@ -154,7 +151,7 @@ [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[previousUIObject]-right-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:@{@"right":@(spaceAroundObjectPrevious.right)} views:NSDictionaryOfVariableBindings(previousUIObject)]]; } } - + + (void)autoLayoutViewWithConstrainingViewsWithUIArray:(nonnull NSArray *)formUIArray withSpacingBlock:(nonnull UIEdgeInsets (^) (id _Nullable object))spacingBlock { if ([formUIArray count] > 0) { @@ -188,16 +185,9 @@ } } -- (void)resetSpaceForFormArrayWithConstrainingViews { - for (UIView *view in self.formUIArray) { - ViewConstrainingView *constrainingView = (ViewConstrainingView *)view.superview; - [constrainingView setPinConstantsWithInsets:[self spaceAroundUIObject:view]]; - } -} - -+ (UIEdgeInsets)standardSpaceAroundUIObject { - CGFloat horizontal = [MFStyler defaultHorizontalPaddingForApplicationWidth]; - CGFloat vertical = [MFStyler defaultVerticalPaddingForApplicationWidth]; ++ (UIEdgeInsets)standardSpaceAroundUIObjectForSize:(CGFloat)size { + CGFloat horizontal = [MFStyler defaultHorizontalPaddingForSize:size]; + CGFloat vertical = [MFStyler defaultVerticalPaddingForSize:size]; return UIEdgeInsetsMake(vertical, horizontal, 0, horizontal); } diff --git a/MVMCoreUI/BaseControllers/TopLabelsAndBottomButtonsViewController.h b/MVMCoreUI/BaseControllers/MVMCoreUIThreeLayerViewController.h similarity index 77% rename from MVMCoreUI/BaseControllers/TopLabelsAndBottomButtonsViewController.h rename to MVMCoreUI/BaseControllers/MVMCoreUIThreeLayerViewController.h index 7d15d543..4304fd23 100644 --- a/MVMCoreUI/BaseControllers/TopLabelsAndBottomButtonsViewController.h +++ b/MVMCoreUI/BaseControllers/MVMCoreUIThreeLayerViewController.h @@ -1,20 +1,16 @@ // -// TopLabelsAndBottomButtonsViewController.h -// myverizon +// MVMCoreUIThreeLayerViewController.h +// MVMCoreUI // -// Created by Scott Pfeil on 1/26/16. -// Copyright © 2016 Verizon Wireless. All rights reserved. +// Created by Scott Pfeil on 2/1/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. // -// Has top labels docked on top, buttons docked on bottom, and anything you'd like in between when subclassed. -#import -#import -#import - -@class LabelView; +#import +@class TopLabelsView; @class PrimaryButton; -@interface TopLabelsAndBottomButtonsViewController : StackableViewController +@interface MVMCoreUIThreeLayerViewController : MVMCoreUIStackableViewController @property (nullable, weak, nonatomic) TopLabelsView *topLabelsView; @property (nullable, weak, nonatomic) PrimaryButton *primaryButton; @@ -24,6 +20,7 @@ @property (nullable, weak, nonatomic) UIView *viewInScroll; @property (nullable, weak, nonatomic) UIView *viewOutOfScroll; @property (nullable, strong, nonatomic) UIView *safeAreaView; +@property (nonatomic, readonly) BOOL customBottomView; // 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. @@ -33,13 +30,11 @@ // The constraint connecting the topLabelsView to the content view. @property (nullable, strong, nonatomic) NSLayoutConstraint *topConstraintForTopView; -// Can override. This is put in because to cover 90% of the screens for initial ipad release, need to rebuild ui (newDataBuildScreen) of size of view change in updateViews. Disable this to handle manually with more finess. -@property (nonatomic) BOOL rebuildUIOnSizeChange; - #pragma mark - Subclass // Allow you to add any additional ui before buildViewsBetweenLabelsAndButtons gets called. Can use this to set the topBetweenEdgeView or bottomBetweenEdgeView - (void)buildInAdditionalViewsBeforeCenteredContent; + // For subclassing. Should return all the views that will be in between labels and buttons. Override standardSpaceAroundUIObject to handle spacing. - (nullable NSArray *)buildViewsBetweenLabelsAndButtons; @@ -53,8 +48,8 @@ - (nullable NSNumber *)spaceBelowBetweenView; // Can overwrite the default padding for labels and buttons. -- (UIEdgeInsets)paddingForTopLabels; -- (UIEdgeInsets)paddingForBottomButtons; +- (void)updateTopLabelsPadding:(CGFloat)size; +- (void)updateBottomButtonsPadding:(CGFloat)size; // default button map will automatically get from response, you can also overide this to have your own button map - (nullable NSDictionary *)secondaryButtonMap; diff --git a/MVMCoreUI/BaseControllers/TopLabelsAndBottomButtonsViewController.m b/MVMCoreUI/BaseControllers/MVMCoreUIThreeLayerViewController.m similarity index 79% rename from MVMCoreUI/BaseControllers/TopLabelsAndBottomButtonsViewController.m rename to MVMCoreUI/BaseControllers/MVMCoreUIThreeLayerViewController.m index cc7cd627..532515ad 100644 --- a/MVMCoreUI/BaseControllers/TopLabelsAndBottomButtonsViewController.m +++ b/MVMCoreUI/BaseControllers/MVMCoreUIThreeLayerViewController.m @@ -1,32 +1,29 @@ // -// TopLabelsAndBottomButtonsViewController.m -// myverizon +// MVMCoreUIThreeLayerViewController.m +// MVMCoreUI // -// Created by Scott Pfeil on 1/26/16. -// Copyright © 2016 Verizon Wireless. All rights reserved. +// Created by Scott Pfeil on 2/1/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. // -#import "TopLabelsAndBottomButtonsViewController.h" -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import -#import - +#import "MVMCoreUIThreeLayerViewController.h" +#import "ViewConstrainingView.h" +#import "MFStyler.h" +#import "MFSizeObject.h" +#import "TopLabelsView.h" +#import "PrimaryButtonView.h" +#import "MVMCoreUICommonViewsUtility.h" +#import "UIColor+MFConvenience.h" +#import "NSLayoutConstraint+MFConvenience.h" +#import "MVMCoreUIConstants.h" @import MVMAnimationFramework; -@interface TopLabelsAndBottomButtonsViewController () +@interface MVMCoreUIThreeLayerViewController () @property (nullable, strong, nonatomic) NSLayoutConstraint *heightConstraint; @property (nullable, weak, nonatomic) UIView *topView; @property (nullable, weak, nonatomic) UIView *bottomView; -@property (nonatomic) BOOL customBottemView; +@property (nonatomic, readwrite) BOOL customBottomView; @property (nullable, weak, nonatomic) NSArray *middleViews; @property (nullable, weak, nonatomic) UIView *betweenView; @@ -38,55 +35,46 @@ @end -@implementation TopLabelsAndBottomButtonsViewController - -- (void)initialLoad { - [super initialLoad]; - self.rebuildUIOnSizeChange = YES; -} +@implementation MVMCoreUIThreeLayerViewController - (void)updateViews { [super updateViews]; - if ([self screenSizeChanged]) { - if (self.rebuildUIOnSizeChange) { - - // If the screen size changed.... just rebuild everything.... this will cover all sizes and help for ipad slide over. - [self newDataBuildScreen]; - } else { - - // Update top labels and bottom buttons. - CGFloat width = CGRectGetWidth(self.view.bounds); - if ([self.topView respondsToSelector:@selector(updateView:)]) { - [((UIView *)self.topView) updateView:width]; - } - if ([self.bottomView respondsToSelector:@selector(updateView:)]) { - [((UIView *)self.bottomView) updateView:width]; - } - [self updateTopLabelsBottomButtonsPadding]; - [self.bottomAccessoryView updateView:width]; - [self resetSpaceForFormArrayWithConstrainingViews]; - } + // Update top labels and bottom buttons. + CGFloat width = CGRectGetWidth(self.view.bounds); + if ([self.topView respondsToSelector:@selector(updateView:)]) { + [((UIView *)self.topView) updateView:width]; + } + if ([self.bottomView respondsToSelector:@selector(updateView:)]) { + [((UIView *)self.bottomView) updateView:width]; + } + [self updateTopLabelsPadding:width]; + [self updateBottomButtonsPadding:width]; + [self.bottomAccessoryView updateView:width]; + [self.bottomAccessoryView setPinConstantsWithInsets:[self spaceAroundUIObject:self.bottomAccessoryView size:width]]; + +} + +- (void)updateTopLabelsPadding:(CGFloat)size { + if (self.topLabelsView) { + CGFloat horizontalPadding = [MFStyler defaultHorizontalPaddingForSize:size]; + self.topLabelsView.topLabelConstraint.constant = PaddingFive; + self.topLabelsView.bottomLabelConstraint.constant = PaddingFive; + [self.topLabelsView setLeftConstant:horizontalPadding]; + [self.topLabelsView setRightConstant:horizontalPadding]; } } -- (void)updateTopLabelsBottomButtonsPadding { - if (self.topLabelsView) { - UIEdgeInsets paddingForTopLabels = [self paddingForTopLabels]; - self.topLabelsView.topLabelConstraint.constant = paddingForTopLabels.top; - self.topLabelsView.bottomLabelConstraint.constant = paddingForTopLabels.bottom; - [self.topLabelsView setLeftConstant:paddingForTopLabels.left]; - [self.topLabelsView setRightConstant:paddingForTopLabels.right]; - } - - if (!self.customBottemView) { +- (void)updateBottomButtonsPadding:(CGFloat)size { + if (!self.customBottomView) { PrimaryButtonView *buttonView = (PrimaryButtonView *)self.bottomView; if (self.secondaryButton || self.primaryButton) { - UIEdgeInsets paddingForBottomButtons = [self paddingForBottomButtons]; - buttonView.leftPin.constant = paddingForBottomButtons.left; - buttonView.rightPin.constant = paddingForBottomButtons.right; - buttonView.topPin.constant = paddingForBottomButtons.top; - buttonView.bottomPin.constant = paddingForBottomButtons.bottom; + // Smaller space for smaller devices. Also, top is 0 by default when in scroll. + CGFloat verticalSpacing = [[MFSizeObject sizeObjectWithStandardSize:PaddingDefaultVerticalSpacing smalliPhoneSize:PaddingDefault] getValueBasedOnScreenSize]; + buttonView.leftPin.constant = PaddingDefaultHorizontalSpacing; + buttonView.rightPin.constant = PaddingDefaultHorizontalSpacing; + buttonView.topPin.constant = [self bottomViewOutsideOfScroll] ? verticalSpacing : 0; + buttonView.bottomPin.constant = verticalSpacing; } else { buttonView.topPin.constant = 0; buttonView.bottomPin.constant = 0; @@ -101,7 +89,7 @@ // Removes the bottom view out of scroll if it is there. [self.viewOutOfScroll removeFromSuperview]; - [StackableViewController removeUIViews:[self.contentView subviews]]; + [MVMCoreUIStackableViewController removeUIViews:[self.contentView subviews]]; // Checks if we are using a different object than top labels. UIView *topView = [self useCustomViewInsteadOfLabels]; @@ -112,7 +100,7 @@ topLabelsView.separatorView.hidden = NO; self.topLabelsView = topLabelsView; topView = topLabelsView; - self.topView = topView; + self.topView = topView; [topLabelsView setWithJSON:[self mapForTopLabels]]; } [self.contentView addSubview:topView]; @@ -122,8 +110,8 @@ // Checks if we are using a different object than the bottom buttons. UIView *bottomView = [self useCustomViewInsteadOfButtons]; - self.customBottemView = (bottomView != nil); - if (!self.customBottemView) { + self.customBottomView = (bottomView != nil); + if (!self.customBottomView) { // Sets up the buttons/button. NSDictionary *primaryButtonDictionary = [self primaryButtonMap]; @@ -133,21 +121,20 @@ self.primaryButton = buttonView.primaryButton; bottomView = buttonView; self.bottomView = bottomView; - } else { - self.bottomView = bottomView; - } - [self updateTopLabelsBottomButtonsPadding]; + } else { + self.bottomView = bottomView; + } // Adds the bottom view outside the scroll if directed. [self.safeAreaView removeFromSuperview]; if ([self bottomViewOutsideOfScroll]) { - if (!self.customBottemView) { + if (!self.customBottomView) { bottomView.backgroundColor = [UIColor mfBackgroundGray]; } [self addViewOutsideOfScrollView:bottomView]; self.viewOutOfScroll = bottomView; - + // Sets this so that the button view added to the content view will be empty. bottomView = [ViewConstrainingView emptyView]; } @@ -159,7 +146,7 @@ // Allows addition of any custom ui before custom center view. [self buildInAdditionalViewsBeforeCenteredContent]; - + // Positions the views in between the labels and buttons. UIView *viewBetween = nil; @@ -221,18 +208,18 @@ NSLayoutConstraint *sameHeightSpacer = [NSLayoutConstraint constraintWithItem:topSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:bottomSpacer attribute:NSLayoutAttributeHeight multiplier:1.0 constant:0]; sameHeightSpacer.active = YES; - + NSLayoutConstraint *minimumHeightSpacer = [NSLayoutConstraint constraintWithItem:topSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:PaddingDefaultVerticalSpacing]; minimumHeightSpacer.active = YES; - + [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[topBetweenEdgeView]-0-[topSpacer]-0-[viewBetween]-0-[bottomSpacer]-0-[bottomBetweenEdgeView]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(topBetweenEdgeView,topSpacer,viewBetween,bottomSpacer,bottomBetweenEdgeView)]]; } else if (spaceAbove) { - + // Space above is set, space below is free. UIView *bottomSpacer = [MVMCoreUICommonViewsUtility commonView]; [self.contentView addSubview:bottomSpacer]; [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[bottomSpacer]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(bottomSpacer)]]; - + NSLayoutConstraint *bottomSpacerHeight = [NSLayoutConstraint constraintWithItem:bottomSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:PaddingDefaultVerticalSpacing]; bottomSpacerHeight.active = YES; @@ -244,7 +231,7 @@ UIView *topSpacer = [MVMCoreUICommonViewsUtility commonView]; [self.contentView addSubview:topSpacer]; [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[topSpacer]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(topSpacer)]]; - + NSLayoutConstraint *topSpacerHeight = [NSLayoutConstraint constraintWithItem:topSpacer attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:PaddingDefaultVerticalSpacing]; topSpacerHeight.active = YES; @@ -258,7 +245,7 @@ UIView *spacer = [MVMCoreUICommonViewsUtility commonView]; [self.contentView addSubview:spacer]; [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0-[spacer]-0-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(spacer)]]; - + // Needs the height constraint heightConstraint.active = YES; @@ -286,19 +273,14 @@ // Do any additional setup after loading the view. } -- (UIEdgeInsets)spaceAroundUIObject:(nullable id)object { - CGFloat horizontal = [MFStyler defaultHorizontalPaddingForApplicationWidth]; +- (UIEdgeInsets)spaceAroundUIObject:(nullable id)object size:(CGFloat)size { + CGFloat horizontal = [MFStyler defaultHorizontalPaddingForSize:size]; if (self.bottomAccessoryView == object) { return UIEdgeInsetsMake(0, horizontal, PaddingDefaultVerticalSpacing, horizontal); } return UIEdgeInsetsMake(0, horizontal, 0, horizontal); } -- (void)didReceiveMemoryWarning { - [super didReceiveMemoryWarning]; - // Dispose of any resources that can be recreated. -} - - (void)addViewToContentView:(UIView *)bottomView { self.bottomConstraint.active = YES; @@ -313,10 +295,10 @@ - (void)addViewOutsideOfScrollView:(UIView *)bottomView { self.bottomConstraint.active = NO; - + // Buttons will be outside of the scrolling view. [self.view addSubview:bottomView]; - + UIScrollView *scrollview = self.scrollView; if (@available(iOS 11.0, *)) { [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:[scrollview]-0-[bottomView]" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(scrollview,bottomView)]]; @@ -334,7 +316,6 @@ #pragma mark - Can Subclass These - - (nullable UIView *)buttonsAccessoryView { return nil; } @@ -349,8 +330,6 @@ [self.contentView addSubview:constrainingView]; self.bottomBetweenEdgeView = constrainingView; self.bottomAccessoryView = constrainingView; - - [constrainingView setPinConstantsWithInsets:[self spaceAroundUIObject:constrainingView]]; [NSLayoutConstraint constraintPinLeftSubview:constrainingView leftConstant:0]; [NSLayoutConstraint constraintPinRightSubview:constrainingView rightConstant:0]; @@ -373,23 +352,12 @@ return nil; } -- (UIEdgeInsets)paddingForTopLabels { - return UIEdgeInsetsMake(PaddingFive, [MFStyler defaultHorizontalPaddingForApplicationWidth], PaddingDefaultVerticalSpacing, [MFStyler defaultHorizontalPaddingForApplicationWidth]); -} - -- (UIEdgeInsets)paddingForBottomButtons { - - // Smaller space for smaller devices. Also, top is 0 by default when in scroll. - CGFloat verticalSpacing = [[MFSizeObject sizeObjectWithStandardSize:PaddingDefaultVerticalSpacing smalliPhoneSize:PaddingDefault] getValueBasedOnScreenSize]; - return UIEdgeInsetsMake(([self bottomViewOutsideOfScroll] ? verticalSpacing : 0), PaddingDefaultHorizontalSpacing, verticalSpacing, PaddingDefaultHorizontalSpacing); -} - -- (NSDictionary*)primaryButtonMap { +- (NSDictionary *)primaryButtonMap { NSDictionary *buttonMap = [self.loadObject.pageJSON dict:KeyButtonMap]; return [buttonMap dict:KeyPrimaryButton]; } -- (NSDictionary*)secondaryButtonMap { +- (NSDictionary *)secondaryButtonMap { NSDictionary *buttonMap = [self.loadObject.pageJSON dict:KeyButtonMap]; return [buttonMap dict:KeySecondaryButton]; } @@ -410,10 +378,8 @@ return NO; } - - #pragma mark - Animations --(void)setupIntroAnimations { +- (void)setupIntroAnimations { if (self.topView.subviews) { [self.introAnimationManager addAnimationWithAnimation:[MVMAnimations fadeUpAnimationWithView:self.topView]]; } @@ -422,13 +388,6 @@ [self.introAnimationManager addAnimationWithAnimation:[MVMAnimations fadeUpAnimationWithView:self.topBetweenEdgeView]]; } -// NSMutableArray *centerAnimationObjects = [NSMutableArray new]; -// for (int i = 0; i < self.middleViews.count; i++) { -// MVMAnimationObject *aobj =[MVMAnimations fadeUpAnimationWithView:self.middleViews[i]]; -// [centerAnimationObjects addObject:aobj]; -// } -// [self.introAnimationManager addAnimationGroupWithAnimations:centerAnimationObjects]; - [self.introAnimationManager addAnimationWithAnimation:[MVMAnimations fadeUpAnimationWithView:self.betweenView]]; if (self.bottomBetweenEdgeView.subviews.count) { diff --git a/MVMCoreUI/LegacyControllers/StackableViewController.h b/MVMCoreUI/LegacyControllers/StackableViewController.h new file mode 100644 index 00000000..49984150 --- /dev/null +++ b/MVMCoreUI/LegacyControllers/StackableViewController.h @@ -0,0 +1,23 @@ +// +// StackableViewController.h +// myverizon +// +// Created by Scott Pfeil on 3/26/14. +// Copyright (c) 2014 Verizon Wireless. All rights reserved. +// +// This view controller is here to enable faster development of standard form screens. Put all ui objects that you want to be displayed in a top down order in an array and then call the generateFormWithUIArray. Any type can go in it. + +#import + +@interface StackableViewController : MVMCoreUIStackableViewController + +// Returns the spacing that should surround the passed in item. Subclass this to change spacing. +- (UIEdgeInsets)spaceAroundUIObject:(nullable id)object; + +// When using constraining views in the form array, resets the space that should surround each element. +- (void)resetSpaceForFormArrayWithConstrainingViews; + +// Returns the standard space around ui objects. ++ (UIEdgeInsets)standardSpaceAroundUIObject; + +@end diff --git a/MVMCoreUI/LegacyControllers/StackableViewController.m b/MVMCoreUI/LegacyControllers/StackableViewController.m new file mode 100644 index 00000000..f2dd9fe1 --- /dev/null +++ b/MVMCoreUI/LegacyControllers/StackableViewController.m @@ -0,0 +1,43 @@ +// +// StackableViewController.m +// myverizon +// +// Created by Scott Pfeil on 3/26/14. +// Copyright (c) 2014 Verizon Wireless. All rights reserved. +// + +#import "StackableViewController.h" +#import "MFStyler.h" +#import "ViewConstrainingView.h" +#import "MVMCoreUIUtility.h" + +@interface StackableViewController () + +@end + +@implementation StackableViewController + +- (UIEdgeInsets)spaceAroundUIObject:(nullable id)object { + return [super spaceAroundUIObject:object size:[MVMCoreUIUtility getWidth]]; +} + +- (UIEdgeInsets)spaceAroundUIObject:(nullable id)object size:(CGFloat)size { + return [self spaceAroundUIObject:object]; +} + +- (void)resetSpaceForFormArrayWithConstrainingViews { + for (UIView *view in self.formUIArray) { + ViewConstrainingView *constrainingView = (ViewConstrainingView *)view.superview; + [constrainingView setPinConstantsWithInsets:[self spaceAroundUIObject:view]]; + } +} + ++ (UIEdgeInsets)standardSpaceAroundUIObject { + return [super standardSpaceAroundUIObjectForSize:[MVMCoreUIUtility getWidth]]; +} + ++ (UIEdgeInsets)standardSpaceAroundUIObjectForSize:(CGFloat)size { + return [self standardSpaceAroundUIObject]; +} + +@end diff --git a/MVMCoreUI/BaseControllers/TopLabelsAndBottomButtonsTableViewController.h b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsTableViewController.h similarity index 100% rename from MVMCoreUI/BaseControllers/TopLabelsAndBottomButtonsTableViewController.h rename to MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsTableViewController.h diff --git a/MVMCoreUI/BaseControllers/TopLabelsAndBottomButtonsTableViewController.m b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsTableViewController.m similarity index 100% rename from MVMCoreUI/BaseControllers/TopLabelsAndBottomButtonsTableViewController.m rename to MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsTableViewController.m diff --git a/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.h b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.h new file mode 100644 index 00000000..82fb809a --- /dev/null +++ b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.h @@ -0,0 +1,28 @@ +// +// TopLabelsAndBottomButtonsViewController.h +// myverizon +// +// Created by Scott Pfeil on 1/26/16. +// Copyright © 2016 Verizon Wireless. All rights reserved. +// +// Has top labels docked on top, buttons docked on bottom, and anything you'd like in between when subclassed. + +#import +#import +#import +#import +@class LabelView; + +@interface TopLabelsAndBottomButtonsViewController : MVMCoreUIThreeLayerViewController + +// Can override. This is put in because to cover 90% of the screens for initial ipad release, need to rebuild ui (newDataBuildScreen) of size of view change in updateViews. Disable this to handle manually with more finess. +@property (nonatomic) BOOL rebuildUIOnSizeChange; + +// Can overwrite the default padding for labels and buttons. +- (UIEdgeInsets)paddingForTopLabels; +- (UIEdgeInsets)paddingForBottomButtons; + +// Returns the spacing that should surround the passed in item. Subclass this to change spacing. +- (UIEdgeInsets)spaceAroundUIObject:(nullable id)object; + +@end diff --git a/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.m b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.m new file mode 100644 index 00000000..2f169286 --- /dev/null +++ b/MVMCoreUI/LegacyControllers/TopLabelsAndBottomButtonsViewController.m @@ -0,0 +1,92 @@ +// +// TopLabelsAndBottomButtonsViewController.m +// myverizon +// +// Created by Scott Pfeil on 1/26/16. +// Copyright © 2016 Verizon Wireless. All rights reserved. +// + +#import "TopLabelsAndBottomButtonsViewController.h" +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import + +@import MVMAnimationFramework; + +@interface TopLabelsAndBottomButtonsViewController () + +@end + +@implementation TopLabelsAndBottomButtonsViewController + +- (void)initialLoad { + [super initialLoad]; + self.rebuildUIOnSizeChange = YES; +} + +- (void)updateViews { + if ([self screenSizeChanged] && self.rebuildUIOnSizeChange) { + + // If the screen size changed.... just rebuild everything.... this will cover all sizes and help for ipad slide over. + [self newDataBuildScreen]; + } + [super updateViews]; +} + +- (UIEdgeInsets)spaceAroundUIObject:(nullable id)object { + return [super spaceAroundUIObject:object size:[MVMCoreUIUtility getWidth]]; +} + +- (UIEdgeInsets)spaceAroundUIObject:(id)object size:(CGFloat)size { + return [self spaceAroundUIObject:object]; +} + +- (UIEdgeInsets)paddingForTopLabels { + return UIEdgeInsetsMake(PaddingFive, [MFStyler defaultHorizontalPaddingForApplicationWidth], PaddingDefaultVerticalSpacing, [MFStyler defaultHorizontalPaddingForApplicationWidth]); +} + +- (UIEdgeInsets)paddingForBottomButtons { + // Smaller space for smaller devices. Also, top is 0 by default when in scroll. + CGFloat verticalSpacing = [[MFSizeObject sizeObjectWithStandardSize:PaddingDefaultVerticalSpacing smalliPhoneSize:PaddingDefault] getValueBasedOnScreenSize]; + return UIEdgeInsetsMake(([self bottomViewOutsideOfScroll] ? verticalSpacing : 0), PaddingDefaultHorizontalSpacing, verticalSpacing, PaddingDefaultHorizontalSpacing); +} + +- (void)updateTopLabelsPadding:(CGFloat)size { + if (self.topLabelsView) { + UIEdgeInsets paddingForTopLabels = [self paddingForTopLabels]; + self.topLabelsView.topLabelConstraint.constant = paddingForTopLabels.top; + self.topLabelsView.bottomLabelConstraint.constant = paddingForTopLabels.bottom; + [self.topLabelsView setLeftConstant:paddingForTopLabels.left]; + [self.topLabelsView setRightConstant:paddingForTopLabels.right]; + } +} + +- (void)updateBottomButtonsPadding:(CGFloat)size { + if (!self.customBottomView) { + PrimaryButtonView *buttonView = (PrimaryButtonView *)self.bottomView; + if (self.secondaryButton || self.primaryButton) { + UIEdgeInsets paddingForBottomButtons = [self paddingForBottomButtons]; + buttonView.leftPin.constant = paddingForBottomButtons.left; + buttonView.rightPin.constant = paddingForBottomButtons.right; + buttonView.topPin.constant = paddingForBottomButtons.top; + buttonView.bottomPin.constant = paddingForBottomButtons.bottom; + } else { + buttonView.topPin.constant = 0; + buttonView.bottomPin.constant = 0; + buttonView.leftPin.constant = 0; + buttonView.rightPin.constant = 0; + } + } +} + +@end diff --git a/MVMCoreUI/MVMCoreUI.h b/MVMCoreUI/MVMCoreUI.h index 7821c746..3ec411ae 100644 --- a/MVMCoreUI/MVMCoreUI.h +++ b/MVMCoreUI/MVMCoreUI.h @@ -49,6 +49,8 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[]; #import #import #import +#import +#import #import #import #import @@ -80,7 +82,10 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[]; #import #import #import -#import +#import +#import +#import +#import #pragma mark Buttons #import diff --git a/MVMCoreUI/Molecules/TopLabelsView.m b/MVMCoreUI/Molecules/TopLabelsView.m index 028fcf32..5452871f 100644 --- a/MVMCoreUI/Molecules/TopLabelsView.m +++ b/MVMCoreUI/Molecules/TopLabelsView.m @@ -221,7 +221,10 @@ self.headlineLabel.textColor = textColor; self.messageLabel.textColor = textColor; self.backgroundColor = [self colorForBackgroundWithJSON:json]; - self.separatorView.hidden = ![json boolForKey:@"showBottomLine"]; + NSNumber *showBottomLine = [json objectForKey:@"showBottomLine" ofType:[NSNumber class]]; + if (showBottomLine) { + self.separatorView.hidden = ![showBottomLine boolValue]; + } } - (nonnull UIColor *)colorForTopLabelsWithJSON:(nullable NSDictionary *)json { diff --git a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings index 477a47d0..472bb9b6 100644 --- a/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/en.lproj/Localizable.strings @@ -29,3 +29,13 @@ // Camera "AccCameraButton" = "Camera Button"; "AccCameraHint" = "Double tap to launch camera for scanning"; +// Checkbox +"checkbox_action_hint" = "Double tap to change state"; +"checkbox_checked_state" = "Checked"; +"checkbox_unchecked_state" = "Unchecked"; +"checkbox_desc_state" = "%@ CheckBox %@"; +// Switch +"mfswitch_buttonlabel" = "Switch Button"; +"AccOn" = "on"; +"AccOff" = "off"; +"AccToggleHint" = "double tap to toggle"; diff --git a/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings index caeb41c4..f640133a 100644 --- a/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/es-MX.lproj/Localizable.strings @@ -7,11 +7,14 @@ */ "AccCloseButton" = "Cerrar"; +// Tab "AccTab" = ", pestaña"; "AccTabHint" = "Toca dos veces para seleccionar."; +// top alert "toptabbar_tab_selected" = ", pestaña, Seleccionado"; "AccTopAlertClosed" = "La notificación de alerta máxima está desactivada."; "top_alert_notification" = "Notificación de alerta máxima"; +// Textfield "textfield_today_string" = "Hoy"; "textfield_error_message" = "%@.\n El mensaje de error.\n %@"; "textfield_picker_item" = " artículo de selector"; @@ -25,3 +28,13 @@ // Camera "AccCameraButton" = "Botón de cámara"; "AccCameraHint" = "Toca dos veces para iniciar la cámara para escanear"; +// Checkbox +"checkbox_action_hint" = "Toca dos veces para cambiar el estado"; +"checkbox_checked_state" = "Verificado"; +"checkbox_unchecked_state" = "Sin marcar"; +"checkbox_desc_state" = "%@ Casilla %@"; +// Switch +"mfswitch_buttonlabel" = "Botón Cambiar"; +"AccOn" = "encendido"; +"AccOff" = "apagado"; +"AccToggleHint" = "toca dos veces para alternar"; diff --git a/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings b/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings index caeb41c4..f640133a 100644 --- a/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings +++ b/MVMCoreUI/SupportingFiles/Strings/es.lproj/Localizable.strings @@ -7,11 +7,14 @@ */ "AccCloseButton" = "Cerrar"; +// Tab "AccTab" = ", pestaña"; "AccTabHint" = "Toca dos veces para seleccionar."; +// top alert "toptabbar_tab_selected" = ", pestaña, Seleccionado"; "AccTopAlertClosed" = "La notificación de alerta máxima está desactivada."; "top_alert_notification" = "Notificación de alerta máxima"; +// Textfield "textfield_today_string" = "Hoy"; "textfield_error_message" = "%@.\n El mensaje de error.\n %@"; "textfield_picker_item" = " artículo de selector"; @@ -25,3 +28,13 @@ // Camera "AccCameraButton" = "Botón de cámara"; "AccCameraHint" = "Toca dos veces para iniciar la cámara para escanear"; +// Checkbox +"checkbox_action_hint" = "Toca dos veces para cambiar el estado"; +"checkbox_checked_state" = "Verificado"; +"checkbox_unchecked_state" = "Sin marcar"; +"checkbox_desc_state" = "%@ Casilla %@"; +// Switch +"mfswitch_buttonlabel" = "Botón Cambiar"; +"AccOn" = "encendido"; +"AccOff" = "apagado"; +"AccToggleHint" = "toca dos veces para alternar"; diff --git a/MVMCoreUI/Templates/MVMCoreUILargeHeaderSingleLabelTemplate.h b/MVMCoreUI/Templates/MVMCoreUILargeHeaderSingleLabelTemplate.h index a73dd8cc..4957f306 100644 --- a/MVMCoreUI/Templates/MVMCoreUILargeHeaderSingleLabelTemplate.h +++ b/MVMCoreUI/Templates/MVMCoreUILargeHeaderSingleLabelTemplate.h @@ -7,12 +7,11 @@ // #import -#import +#import @class LabelView; @class LabelWithInternalButton; -NS_ASSUME_NONNULL_BEGIN -@interface MVMCoreUILargeHeaderSingleLabelTemplate : TopLabelsAndBottomButtonsViewController +@interface MVMCoreUILargeHeaderSingleLabelTemplate : MVMCoreUIThreeLayerViewController // A label that can go below the top labels. Can be a normal label or one with internal buttons. @property (nullable, weak, nonatomic) LabelView *labelViewUnderTopLabels; @@ -25,5 +24,3 @@ NS_ASSUME_NONNULL_BEGIN - (nullable NSDictionary *)actionMapForLabelUnderTopLabelsWithInternalButton; @end - -NS_ASSUME_NONNULL_END diff --git a/MVMCoreUI/Templates/MVMCoreUILargeHeaderSingleLabelTemplate.m b/MVMCoreUI/Templates/MVMCoreUILargeHeaderSingleLabelTemplate.m index 6f00dc6e..563fdbdd 100644 --- a/MVMCoreUI/Templates/MVMCoreUILargeHeaderSingleLabelTemplate.m +++ b/MVMCoreUI/Templates/MVMCoreUILargeHeaderSingleLabelTemplate.m @@ -10,6 +10,7 @@ #import "LabelView.h" #import "LabelWithInternalButton.h" #import "UIColor+MFConvenience.h" +#import "TopLabelsView.h" @interface MVMCoreUILargeHeaderSingleLabelTemplate () @@ -20,11 +21,7 @@ - (void)newDataBuildScreen { [super newDataBuildScreen]; [self.topLabelsView.headlineLabel setFontH1:YES]; -} - -- (void)initialLoad { - [super initialLoad]; - self.rebuildUIOnSizeChange = NO; + [self.topLabelsView.separatorView hide]; } - (nullable NSArray *)buildViewsBetweenLabelsAndButtons { @@ -75,10 +72,9 @@ // Dispose of any resources that can be recreated. } -- (UIEdgeInsets)paddingForTopLabels { - UIEdgeInsets edge = [super paddingForTopLabels]; - edge.bottom = PaddingTwo; - return edge; +- (void)updateTopLabelsPadding:(CGFloat)size { + [super updateTopLabelsPadding:size]; + self.topLabelsView.bottomLabelConstraint.constant = PaddingTwo; } @end diff --git a/MVMCoreUI/Utility/MVMCoreUIUtility.h b/MVMCoreUI/Utility/MVMCoreUIUtility.h index 6f85f6d2..81545583 100644 --- a/MVMCoreUI/Utility/MVMCoreUIUtility.h +++ b/MVMCoreUI/Utility/MVMCoreUIUtility.h @@ -49,6 +49,9 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Sizing +// Grabs the width from the available container. ++ (CGFloat)getWidth; + // Gets the space needed at the top of the view for the status bar. + (CGFloat)getTopSpaceWithStatusBarForView:(UIView *_Nonnull)view; diff --git a/MVMCoreUI/Utility/MVMCoreUIUtility.m b/MVMCoreUI/Utility/MVMCoreUIUtility.m index dfcc970b..c0135d4f 100644 --- a/MVMCoreUI/Utility/MVMCoreUIUtility.m +++ b/MVMCoreUI/Utility/MVMCoreUIUtility.m @@ -8,6 +8,7 @@ #import "MVMCoreUIUtility.h" #import "MVMCoreUIConstants.h" +#import "MVMCoreUISession.h" @import MVMCore.MVMCoreNavigationHandler; @import MVMCore.MVMCoreGetterUtility; @@ -97,6 +98,15 @@ #pragma mark - Sizing ++ (CGFloat)getWidth { + UIViewController *controller = [MVMCoreUISession sharedGlobal].splitViewController ?: [MVMCoreUISession sharedGlobal].navigationController ?: [UIApplication sharedApplication].keyWindow.rootViewController; + if (controller) { + return CGRectGetWidth(controller.view.bounds); + } else { + return CGRectGetWidth([UIScreen mainScreen].bounds); + } +} + + (CGFloat)getTopSpaceWithStatusBarForView:(UIView *)view { CGPoint viewStartPointInWindowSpace = [[UIApplication sharedApplication].keyWindow convertPoint:CGPointMake(CGRectGetMinX(view.frame), CGRectGetMinY(view.frame)) fromView:[view superview]]; if (CGRectGetMaxY([UIApplication sharedApplication].statusBarFrame) > viewStartPointInWindowSpace.y) {