Helper functions
Molecule List. Back to view instead of margins for stack due to background color issues. Standard Header View to margin for internal use.
This commit is contained in:
parent
a45fd12da5
commit
b00b43eab0
@ -147,6 +147,7 @@
|
||||
D29DF32521ED0DA2003B2FB9 /* TextButtonView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF32321ED0DA2003B2FB9 /* TextButtonView.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D29DF32C21EE8736003B2FB9 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = D29DF32821EE8736003B2FB9 /* Localizable.strings */; };
|
||||
D29DF32E21EE8C3D003B2FB9 /* Media.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D29DF32D21EE8C3D003B2FB9 /* Media.xcassets */; };
|
||||
D2A421BF226A14F100A05A88 /* ConstrainingMoleculeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A421BE226A14F100A05A88 /* ConstrainingMoleculeView.swift */; };
|
||||
D2A514582211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D2A514562211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2A514592211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2A514572211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m */; };
|
||||
D2A5145D2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
@ -158,6 +159,9 @@
|
||||
D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */; };
|
||||
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */; };
|
||||
D2E1FADD2268B25E00AEFD8C /* MoleculeTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADC2268B25E00AEFD8C /* MoleculeTableViewCell.swift */; };
|
||||
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */; };
|
||||
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */; };
|
||||
DBC4391822442197001AB423 /* CaretView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391622442196001AB423 /* CaretView.swift */; };
|
||||
DBC4391922442197001AB423 /* DashLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391722442197001AB423 /* DashLine.swift */; };
|
||||
DBC4391B224421A0001AB423 /* CaretButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = DBC4391A224421A0001AB423 /* CaretButton.swift */; };
|
||||
@ -308,6 +312,7 @@
|
||||
D29DF32A21EE8736003B2FB9 /* es */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = es; path = es.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
D29DF32B21EE8736003B2FB9 /* es-MX */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "es-MX"; path = "es-MX.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||
D29DF32D21EE8C3D003B2FB9 /* Media.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Media.xcassets; sourceTree = "<group>"; };
|
||||
D2A421BE226A14F100A05A88 /* ConstrainingMoleculeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConstrainingMoleculeView.swift; sourceTree = "<group>"; };
|
||||
D2A514562211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIMoleculeMappingObject.h; sourceTree = "<group>"; };
|
||||
D2A514572211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIMoleculeMappingObject.m; sourceTree = "<group>"; };
|
||||
D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIMoleculeViewProtocol.h; sourceTree = "<group>"; };
|
||||
@ -319,6 +324,9 @@
|
||||
D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewControllerMappingObject.h; sourceTree = "<group>"; };
|
||||
D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIViewControllerMappingObject.m; sourceTree = "<group>"; };
|
||||
D2E1FADA2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MVMCoreUIDelegateObject.swift; sourceTree = "<group>"; };
|
||||
D2E1FADC2268B25E00AEFD8C /* MoleculeTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeTableViewCell.swift; sourceTree = "<group>"; };
|
||||
D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ThreeLayerTableViewController.swift; sourceTree = "<group>"; };
|
||||
D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeListTemplate.swift; sourceTree = "<group>"; };
|
||||
DBC4391622442196001AB423 /* CaretView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretView.swift; sourceTree = "<group>"; };
|
||||
DBC4391722442197001AB423 /* DashLine.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DashLine.swift; sourceTree = "<group>"; };
|
||||
DBC4391A224421A0001AB423 /* CaretButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CaretButton.swift; sourceTree = "<group>"; };
|
||||
@ -407,6 +415,7 @@
|
||||
01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */,
|
||||
D2A5146022121FBF00345BFB /* MoleculeStackTemplate.swift */,
|
||||
D2A514622213643100345BFB /* MoleculeStackCenteredTemplate.swift */,
|
||||
D2E1FAE02268E81D00AEFD8C /* MoleculeListTemplate.swift */,
|
||||
);
|
||||
path = Templates;
|
||||
sourceTree = "<group>";
|
||||
@ -442,6 +451,7 @@
|
||||
D2A5145C2211D22A00345BFB /* MVMCoreUIMoleculeViewProtocol.h */,
|
||||
D2A5145E2211DDC100345BFB /* MoleculeStackView.swift */,
|
||||
D274CA322236A78900B01B62 /* StandardFooterView.swift */,
|
||||
D2E1FADC2268B25E00AEFD8C /* MoleculeTableViewCell.swift */,
|
||||
);
|
||||
path = Molecules;
|
||||
sourceTree = "<group>";
|
||||
@ -462,6 +472,7 @@
|
||||
D29DF2CC21E7C104003B2FB9 /* MFLoadingViewController.h */,
|
||||
D29DF2CD21E7C104003B2FB9 /* MFLoadingViewController.m */,
|
||||
D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */,
|
||||
D2E1FADE2268B8E700AEFD8C /* ThreeLayerTableViewController.swift */,
|
||||
);
|
||||
path = BaseControllers;
|
||||
sourceTree = "<group>";
|
||||
@ -568,6 +579,7 @@
|
||||
D29DF28621E7AC2B003B2FB9 /* MFLabel.m */,
|
||||
D29DF31E21ED0CBA003B2FB9 /* LabelView.h */,
|
||||
D29DF31F21ED0CBA003B2FB9 /* LabelView.m */,
|
||||
D2A421BE226A14F100A05A88 /* ConstrainingMoleculeView.swift */,
|
||||
D29DF28721E7AC2B003B2FB9 /* ViewConstrainingView.h */,
|
||||
D29DF28821E7AC2B003B2FB9 /* ViewConstrainingView.m */,
|
||||
D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */,
|
||||
@ -868,6 +880,7 @@
|
||||
D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */,
|
||||
DBC4391922442197001AB423 /* DashLine.swift in Sources */,
|
||||
D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */,
|
||||
D2A421BF226A14F100A05A88 /* ConstrainingMoleculeView.swift in Sources */,
|
||||
D2E1FADB2260D3D200AEFD8C /* MVMCoreUIDelegateObject.swift in Sources */,
|
||||
D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */,
|
||||
D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */,
|
||||
@ -897,6 +910,7 @@
|
||||
D29DF2EF21ECEAE1003B2FB9 /* MFFonts.m in Sources */,
|
||||
D282AACB2243C61700C46919 /* ButtonView.swift in Sources */,
|
||||
0105618F224BBE7700E1557D /* FormValidator+FormParams.swift in Sources */,
|
||||
D2E1FADD2268B25E00AEFD8C /* MoleculeTableViewCell.swift in Sources */,
|
||||
D29DF2AE21E7B3A4003B2FB9 /* MFTextView.m in Sources */,
|
||||
D29DF18121E69E50003B2FB9 /* MFView.m in Sources */,
|
||||
D29DF18321E69E54003B2FB9 /* SeparatorView.m in Sources */,
|
||||
@ -913,6 +927,7 @@
|
||||
D29DF2C721E7BF57003B2FB9 /* MFTabBarInteractor.m in Sources */,
|
||||
D29DF29521E7ADB8003B2FB9 /* ProgrammaticScrollViewController.m in Sources */,
|
||||
D29DF16121E69996003B2FB9 /* MFViewController.m in Sources */,
|
||||
D2E1FAE12268E81D00AEFD8C /* MoleculeListTemplate.swift in Sources */,
|
||||
D22D1F47220496A30077CEC0 /* MVMCoreUISwitch.m in Sources */,
|
||||
D29DF28C21E7AC2B003B2FB9 /* ViewConstrainingView.m in Sources */,
|
||||
D29DF17B21E69E1F003B2FB9 /* PrimaryButton.m in Sources */,
|
||||
@ -920,6 +935,7 @@
|
||||
0198F79F225679880066C936 /* FormValidationProtocol.swift in Sources */,
|
||||
D29DF29821E7ADB8003B2FB9 /* MFScrollingViewController.m in Sources */,
|
||||
D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */,
|
||||
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */,
|
||||
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */,
|
||||
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
|
||||
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */,
|
||||
|
||||
55
MVMCoreUI/Atoms/Views/ConstrainingMoleculeView.swift
Normal file
55
MVMCoreUI/Atoms/Views/ConstrainingMoleculeView.swift
Normal file
@ -0,0 +1,55 @@
|
||||
//
|
||||
// ConstrainingMoleculeView.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/19/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@objcMembers open class ConstrainingMoleculeView: MFView {
|
||||
var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)?
|
||||
|
||||
public init(withMolecule molecule: UIView & MVMCoreUIMoleculeViewProtocol) {
|
||||
self.molecule = molecule
|
||||
super.init(frame: .zero)
|
||||
}
|
||||
|
||||
required public init?(coder aDecoder: NSCoder) {
|
||||
super.init(coder: aDecoder)
|
||||
}
|
||||
|
||||
open override func setupView() {
|
||||
super.setupView()
|
||||
if let molecule = molecule, molecule.superview == nil {
|
||||
addSubview(molecule)
|
||||
molecule.topAnchor.constraint(equalTo: topAnchor).isActive = true
|
||||
molecule.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor).isActive = true
|
||||
layoutMarginsGuide.rightAnchor.constraint(equalTo: molecule.rightAnchor).isActive = true
|
||||
bottomAnchor.constraint(equalTo: molecule.bottomAnchor).isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
open override func updateView(_ size: CGFloat) {
|
||||
if let molecule = molecule as? MVMCoreViewProtocol {
|
||||
molecule.updateView(size)
|
||||
}
|
||||
MFStyler.setDefaultMarginsFor(self, size: size)
|
||||
}
|
||||
|
||||
open override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
guard let json = json, let molecule = molecule else {
|
||||
return
|
||||
}
|
||||
molecule.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
if let backgroundColor = molecule.backgroundColor {
|
||||
self.backgroundColor = backgroundColor
|
||||
}
|
||||
}
|
||||
|
||||
open override func setAsMolecule() {
|
||||
molecule?.setAsMolecule?()
|
||||
}
|
||||
}
|
||||
@ -237,6 +237,10 @@
|
||||
self.originalAttributedString = self.attributedText;
|
||||
}
|
||||
|
||||
- (BOOL)needsToBeConstrained {
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)styleH1:(BOOL)scale {
|
||||
[MFStyler styleLabelH1:self genericScaling:NO];
|
||||
[self setScale:scale];
|
||||
|
||||
@ -131,6 +131,7 @@
|
||||
CGFloat padding = [MFStyler defaultHorizontalPaddingForSize:size];
|
||||
[self setLeftPinConstant:padding];
|
||||
[self setRightPinConstant:padding];
|
||||
[MFStyler setDefaultMarginsForView:self size:size];
|
||||
}];
|
||||
}
|
||||
}
|
||||
@ -138,6 +139,7 @@
|
||||
#pragma mark - MVMCoreUIMoleculeViewProtocol
|
||||
|
||||
- (void)setAsMolecule {
|
||||
self.updateViewHorizontalDefaults = YES;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@ -521,6 +521,10 @@
|
||||
} completion:completion];
|
||||
}
|
||||
|
||||
- (BOOL)viewRespectsSystemMinimumLayoutMargins {
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - UITextField Functions
|
||||
|
||||
// To Remove TextFields Bug: Keyboard is not dismissing after reaching textfield max length limit
|
||||
|
||||
255
MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift
Normal file
255
MVMCoreUI/BaseControllers/ThreeLayerTableViewController.swift
Normal file
@ -0,0 +1,255 @@
|
||||
//
|
||||
// ThreeLayerTableViewController.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/18/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
import MVMAnimationFramework
|
||||
|
||||
open class ThreeLayerTableViewController: MFProgrammaticTableViewController {
|
||||
// The three main views
|
||||
private var topView: UIView?
|
||||
private var bottomView: UIView?
|
||||
private var headerView: UIView?
|
||||
private var footerView: UIView?
|
||||
private var safeAreaView: UIView?
|
||||
var useMargins: Bool = true
|
||||
var bottomViewOutsideOfScrollArea: Bool = false
|
||||
private var topViewBottomConstraint: NSLayoutConstraint?
|
||||
private var bottomViewTopConstraint: NSLayoutConstraint?
|
||||
|
||||
//MARK:-MVMCoreViewProtocol
|
||||
open override func updateViews() {
|
||||
super.updateViews()
|
||||
let width = view.bounds.width
|
||||
MFStyler.setDefaultMarginsFor(contentView, size: width)
|
||||
if let topView = topView as? MVMCoreViewProtocol {
|
||||
topView.updateView(width)
|
||||
showHeader()
|
||||
}
|
||||
if let bottomView = bottomView as? MVMCoreViewProtocol {
|
||||
bottomView.updateView(width)
|
||||
showFooter()
|
||||
}
|
||||
self.tableView?.reloadData()
|
||||
}
|
||||
|
||||
//MARK:-MFViewController
|
||||
open override func newDataBuildScreen() {
|
||||
super.newDataBuildScreen()
|
||||
createViewForTableHeader()
|
||||
createViewForTableFooter()
|
||||
tableView?.reloadData()
|
||||
}
|
||||
|
||||
override open func viewDidLoad() {
|
||||
super.viewDidLoad()
|
||||
setToHaveNoSectionHeadersFooters()
|
||||
// Do any additional setup after loading the view.
|
||||
}
|
||||
|
||||
//MARK:-Spacing
|
||||
// If both are subclassed to return a value, then the buttons will not be pinned towards the bottom because neither spacing would try to fill the screen.
|
||||
/// Space between the top view and the table sections, nil to fill. 0 default
|
||||
open func spaceBelowTopView() -> CGFloat? {
|
||||
return 0
|
||||
}
|
||||
|
||||
/// Space between the bottom view and the table sections, nil to fill. nil default
|
||||
open func spaceAboveBottomView() -> CGFloat? {
|
||||
return nil
|
||||
}
|
||||
|
||||
/// can override to return a minimum fill space.
|
||||
open func minimumFillSpace() -> CGFloat {
|
||||
return 0
|
||||
}
|
||||
|
||||
open override func updateViewConstraints() {
|
||||
super.updateViewConstraints()
|
||||
guard let tableView = tableView else {
|
||||
return
|
||||
}
|
||||
|
||||
let minimumSpace: CGFloat = minimumFillSpace()
|
||||
var currentSpace: CGFloat = 0
|
||||
var totalMinimumSpace: CGFloat = 0
|
||||
|
||||
var fillTop = false
|
||||
if spaceBelowTopView() == nil, self.tableView?.tableHeaderView != nil {
|
||||
fillTop = true
|
||||
currentSpace += topViewBottomConstraint?.constant ?? 0
|
||||
totalMinimumSpace += minimumSpace
|
||||
}
|
||||
|
||||
var fillBottom = false
|
||||
if spaceAboveBottomView() == nil, !bottomViewOutsideOfScrollArea, self.tableView?.tableFooterView != nil {
|
||||
fillBottom = true
|
||||
currentSpace += bottomViewTopConstraint?.constant ?? 0
|
||||
totalMinimumSpace += minimumSpace
|
||||
}
|
||||
|
||||
guard fillTop || fillBottom else {
|
||||
return
|
||||
}
|
||||
let newSpace = MVMCoreUIUtility.getVariableConstraintHeight(currentSpace, in: tableView, minimumHeight: totalMinimumSpace)
|
||||
|
||||
// If the bottom view is outside of the scroll, then only the top view constraint is being used, so we have to double it to account for the bottom constraint not being there when we compare to the new value.
|
||||
var currentSpaceForCompare: CGFloat = currentSpace
|
||||
if fillTop && bottomViewOutsideOfScrollArea {
|
||||
currentSpaceForCompare = currentSpace * 2;
|
||||
}
|
||||
|
||||
if !MVMCoreGetterUtility.cgfequalwiththreshold(newSpace, currentSpaceForCompare, 0.1) {
|
||||
if fillTop && fillBottom {
|
||||
// space both
|
||||
let half = newSpace / 2
|
||||
topViewBottomConstraint?.constant = half
|
||||
bottomViewTopConstraint?.constant = half
|
||||
showHeader()
|
||||
showFooter()
|
||||
} else if fillTop {
|
||||
// Only top is spaced (half the size if the bottom view is out of the scroll because it needs to be sized as if there are two spacers but there is only one.
|
||||
if bottomViewOutsideOfScrollArea {
|
||||
topViewBottomConstraint?.constant = newSpace / 2
|
||||
} else {
|
||||
topViewBottomConstraint?.constant = newSpace
|
||||
}
|
||||
showHeader()
|
||||
} else if fillBottom {
|
||||
// Only bottom is spaced.
|
||||
bottomViewTopConstraint?.constant = newSpace
|
||||
showFooter()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//MARK:-Header Footer
|
||||
/// Gets the top view and adds it to a spacing view, headerView, and then calls showHeader.
|
||||
open func createViewForTableHeader() {
|
||||
let topView = viewForTop()
|
||||
self.topView = topView
|
||||
|
||||
let headerView = MVMCoreUICommonViewsUtility.commonView()
|
||||
headerView.addSubview(topView)
|
||||
topView.topAnchor.constraint(equalTo: headerView.topAnchor).isActive = true
|
||||
topView.leftAnchor.constraint(equalTo: headerView.leftAnchor).isActive = true
|
||||
headerView.rightAnchor.constraint(equalTo: topView.rightAnchor).isActive = true
|
||||
topViewBottomConstraint = headerView.bottomAnchor.constraint(equalTo: topView.bottomAnchor, constant: spaceBelowTopView() ?? 0)
|
||||
topViewBottomConstraint?.isActive = true
|
||||
self.headerView = headerView
|
||||
showHeader()
|
||||
}
|
||||
|
||||
/// Gets the bottom view and adds it to a spacing view, footerView, and then calls showFooter.
|
||||
open func createViewForTableFooter() {
|
||||
let bottomView = viewForBottom()
|
||||
self.bottomView = bottomView
|
||||
|
||||
let footerView = MVMCoreUICommonViewsUtility.commonView()
|
||||
footerView.addSubview(bottomView)
|
||||
bottomViewTopConstraint = bottomView.topAnchor.constraint(equalTo: footerView.topAnchor, constant: spaceAboveBottomView() ?? 0)
|
||||
bottomViewTopConstraint?.isActive = true
|
||||
bottomView.leftAnchor.constraint(equalTo: footerView.leftAnchor).isActive = true
|
||||
footerView.rightAnchor.constraint(equalTo: bottomView.rightAnchor).isActive = true
|
||||
footerView.bottomAnchor.constraint(equalTo: bottomView.bottomAnchor).isActive = true
|
||||
self.footerView = footerView
|
||||
showFooter()
|
||||
}
|
||||
|
||||
/// Takes the current headerView and adds it to the tableHeaderView
|
||||
func showHeader() {
|
||||
headerView?.removeFromSuperview()
|
||||
tableView?.tableHeaderView = nil
|
||||
guard let headerView = headerView else {
|
||||
return
|
||||
}
|
||||
|
||||
// This extra view is needed because of the wonkiness of apple's table header. Things breaks if using autolayout.
|
||||
MVMCoreUIUtility.sizeView(toFit: headerView)
|
||||
let tableHeaderView = UIView(frame: CGRect(x: 0, y: 0, width: MVMCoreUIUtility.getWidth(), height: headerView.frame.height))
|
||||
tableHeaderView.addSubview(headerView)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: headerView)
|
||||
tableView?.tableHeaderView = tableHeaderView
|
||||
}
|
||||
|
||||
/// Takes the current footerView and adds it to the tableFooterView
|
||||
func showFooter() {
|
||||
footerView?.removeFromSuperview()
|
||||
safeAreaView?.removeFromSuperview()
|
||||
guard let footerView = footerView, let tableView = tableView else {
|
||||
return
|
||||
}
|
||||
|
||||
if bottomViewOutsideOfScrollArea {
|
||||
// put bottom view outside of scrolling area.
|
||||
bottomConstraint?.isActive = false
|
||||
view.addSubview(footerView)
|
||||
footerView.topAnchor.constraint(equalTo: tableView.bottomAnchor).isActive = true
|
||||
footerView.leftAnchor.constraint(equalTo: view.leftAnchor).isActive = true
|
||||
view.rightAnchor.constraint(equalTo: footerView.rightAnchor).isActive = true
|
||||
if #available(iOS 11.0, *) {
|
||||
view.safeAreaLayoutGuide.bottomAnchor.constraint(equalTo: footerView.bottomAnchor).isActive = true
|
||||
safeAreaView = MVMCoreUICommonViewsUtility.getAndSetupSafeAreaView(on: view)
|
||||
safeAreaView?.backgroundColor = bottomView?.backgroundColor
|
||||
} else {
|
||||
view.bottomAnchor.constraint(equalTo: footerView.bottomAnchor).isActive = true
|
||||
}
|
||||
} else {
|
||||
bottomConstraint?.isActive = true
|
||||
var y: CGFloat?
|
||||
if let tableFooterView = tableView.tableFooterView {
|
||||
// if footer already exists, use the same y location to avoid strange moving animation
|
||||
y = tableFooterView.frame.minY
|
||||
}
|
||||
|
||||
// This extra view is needed because of the wonkiness of apple's table footer. Things breaks if using autolayout.
|
||||
MVMCoreUIUtility.sizeView(toFit: footerView)
|
||||
let tableFooterView = UIView(frame: CGRect(x: 0, y: y ?? 0, width: MVMCoreUIUtility.getWidth(), height: footerView.frame.height))
|
||||
tableFooterView.addSubview(footerView)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: footerView)
|
||||
tableView.tableFooterView = tableFooterView
|
||||
}
|
||||
}
|
||||
|
||||
//MARK:-Functions to subclass
|
||||
/// Subclass for a top view.
|
||||
open func viewForTop() -> UIView {
|
||||
let view = MVMCoreUICommonViewsUtility.commonView()
|
||||
view.heightAnchor.constraint(equalToConstant: 0).isActive = true
|
||||
return view
|
||||
}
|
||||
|
||||
/// Subclass for a bottom view.
|
||||
open func viewForBottom() -> UIView {
|
||||
let view = MVMCoreUICommonViewsUtility.commonView()
|
||||
view.heightAnchor.constraint(equalToConstant: 0).isActive = true
|
||||
return view
|
||||
}
|
||||
|
||||
//MARK:-Scrollview
|
||||
open override func scrollViewDidScroll(_ scrollView: UIScrollView) {
|
||||
// To stop handscroll animation if animating after scroll
|
||||
stopHandScrollAnimation(true)
|
||||
}
|
||||
|
||||
deinit {
|
||||
tableView?.delegate = nil
|
||||
}
|
||||
|
||||
//MARK:-Animation
|
||||
open override func setupIntroAnimations() {
|
||||
if let topView = topView, topView.subviews.count > 0 {
|
||||
introAnimationManager?.addAnimation(animation: MVMAnimations.fadeUpAnimation(view: topView))
|
||||
}
|
||||
if let tableView = tableView {
|
||||
introAnimationManager?.addAnimation(animation: MVMAnimations.animateTableViewFadeInCells(tableView: tableView))
|
||||
}
|
||||
if let bottomView = bottomView, bottomView.subviews.count > 0 {
|
||||
introAnimationManager?.addAnimation(animation: MVMAnimations.fadeUpAnimation(view: bottomView))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -16,7 +16,7 @@ open class ThreeLayerViewController: ProgrammaticScrollViewController {
|
||||
var topView: UIView?
|
||||
var middleView: UIView?
|
||||
var bottomView: UIView?
|
||||
var useMargins: Bool = true
|
||||
var useMargins: Bool = false
|
||||
|
||||
// The bottom view can be put outside of the scrolling area.
|
||||
var bottomViewOutsideOfScroll = false
|
||||
|
||||
@ -19,6 +19,9 @@
|
||||
// Called after init to provide an early setter for any molecule specific logic
|
||||
- (void)setAsMolecule;
|
||||
|
||||
// Notifies the creator that the view needs to be constrained in a view.
|
||||
- (BOOL)needsToBeConstrained;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@ -70,12 +70,9 @@ public class MoleculeStackView: MFView {
|
||||
if let spacingBlock = spacingBlock {
|
||||
MVMCoreUIStackableViewController.populateView(self, withUIArray: moleculesArray, useMargins: useMargins, withSpacingBlock: spacingBlock)
|
||||
} else {
|
||||
let separation = json?.optionalCGFloatForKey("separation") ?? PaddingDefault
|
||||
MVMCoreUIStackableViewController.populateView(self, withUIArray: moleculesArray, useMargins: useMargins) { (object) -> UIEdgeInsets in
|
||||
if object as AnyObject? === moleculesArray.first {
|
||||
return UIEdgeInsets.zero
|
||||
} else {
|
||||
return UIEdgeInsets.init(top: PaddingTwo, left: 0, bottom: 0, right: 0)
|
||||
}
|
||||
return UIEdgeInsets.init(top: separation, left: 0, bottom: 0, right: 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
34
MVMCoreUI/Molecules/MoleculeTableViewCell.swift
Normal file
34
MVMCoreUI/Molecules/MoleculeTableViewCell.swift
Normal file
@ -0,0 +1,34 @@
|
||||
//
|
||||
// MoleculeTableViewCell.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/18/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
@objcMembers open class MoleculeTableViewCell: UITableViewCell, MVMCoreViewProtocol, MVMCoreUIMoleculeViewProtocol {
|
||||
var molecule: (UIView & MVMCoreUIMoleculeViewProtocol)?
|
||||
|
||||
public func updateView(_ size: CGFloat) {
|
||||
if let molecule = molecule as? MVMCoreViewProtocol {
|
||||
molecule.updateView(size)
|
||||
}
|
||||
}
|
||||
|
||||
public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||
guard let json = json else {
|
||||
return
|
||||
}
|
||||
if molecule == nil {
|
||||
if let moleculeView = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForJSON(json, delegateObject: delegateObject) {
|
||||
addSubview(moleculeView)
|
||||
NSLayoutConstraint.constraintPinSubview(toSuperview: moleculeView)
|
||||
molecule = moleculeView
|
||||
}
|
||||
} else {
|
||||
molecule?.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -46,16 +46,16 @@ public class StandardFooterView: ViewConstrainingView {
|
||||
spaceBetweenButtons = textButton.topAnchor.constraint(equalTo: twoButtonView.bottomAnchor, constant: PaddingTwo)
|
||||
spaceBetweenButtons?.isActive = true
|
||||
|
||||
leftConstraintTwoButton = twoButtonView.leftAnchor.constraint(equalTo: leftAnchor)
|
||||
leftConstraintTwoButton = twoButtonView.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor)
|
||||
leftConstraintTwoButton?.isActive = true
|
||||
|
||||
rightConstraintTwoButton = rightAnchor.constraint(equalTo: twoButtonView.rightAnchor)
|
||||
rightConstraintTwoButton = layoutMarginsGuide.rightAnchor.constraint(equalTo: twoButtonView.rightAnchor)
|
||||
rightConstraintTwoButton?.isActive = true
|
||||
|
||||
leftConstraintTextButton = textButton.leftAnchor.constraint(greaterThanOrEqualTo: leftAnchor)
|
||||
leftConstraintTextButton = textButton.leftAnchor.constraint(greaterThanOrEqualTo: layoutMarginsGuide.leftAnchor)
|
||||
leftConstraintTextButton?.isActive = true
|
||||
|
||||
rightConstraintTextButton = rightAnchor.constraint(greaterThanOrEqualTo: textButton.rightAnchor)
|
||||
rightConstraintTextButton = layoutMarginsGuide.rightAnchor.constraint(greaterThanOrEqualTo: textButton.rightAnchor)
|
||||
rightConstraintTextButton?.isActive = true
|
||||
|
||||
centerAlignTextButton = textButton.centerXAnchor.constraint(equalTo: centerXAnchor)
|
||||
@ -93,16 +93,6 @@ public class StandardFooterView: ViewConstrainingView {
|
||||
layoutIfNeeded()
|
||||
}
|
||||
|
||||
public override func setLeftPinConstant(_ constant: CGFloat) {
|
||||
leftConstraintTwoButton?.constant = constant
|
||||
leftConstraintTextButton?.constant = constant
|
||||
}
|
||||
|
||||
public override func setRightPinConstant(_ constant: CGFloat) {
|
||||
rightConstraintTwoButton?.constant = constant
|
||||
rightConstraintTextButton?.constant = constant
|
||||
}
|
||||
|
||||
open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: DelegateObject?, additionalData: [AnyHashable: Any]?) {
|
||||
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||
if let colorString = json?.optionalStringForKey(KeyBackgroundColor) {
|
||||
|
||||
@ -22,7 +22,7 @@
|
||||
static NSMutableDictionary <NSString *, Class>*mapping;
|
||||
dispatch_once(&onceToken, ^{
|
||||
mapping = [@{
|
||||
@"label": LabelView.class,
|
||||
@"label": MFLabel.class,
|
||||
@"separator": SeparatorView.class,
|
||||
@"button": ButtonView.class,
|
||||
@"textButton": MFTextButton.class,
|
||||
@ -47,6 +47,9 @@
|
||||
Class class = [self.moleculeMapping objectForKey:name];
|
||||
if (class) {
|
||||
UIView <MVMCoreUIMoleculeViewProtocol>*view = [[class alloc] init];
|
||||
if ([view respondsToSelector:@selector(needsToBeConstrained)] && [view needsToBeConstrained]) {
|
||||
view = [[ConstrainingMoleculeView alloc] initWithMolecule:view];
|
||||
}
|
||||
if ([view respondsToSelector:@selector(setAsMolecule)]) {
|
||||
[view setAsMolecule];
|
||||
}
|
||||
|
||||
@ -21,7 +21,8 @@
|
||||
viewControllerMapping = [@{
|
||||
@"textFieldListForm" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[TextFieldListFormViewController class]],
|
||||
@"moleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackTemplate class]],
|
||||
@"centerMoleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackCenteredTemplate class]]
|
||||
@"centerMoleculeStack" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeStackCenteredTemplate class]],
|
||||
@"moleculeList" : [[MVMCoreViewControllerProgrammaticMappingObject alloc] initWithClass:[MoleculeListTemplate class]]
|
||||
} mutableCopy];
|
||||
});
|
||||
return viewControllerMapping;
|
||||
|
||||
57
MVMCoreUI/Templates/MoleculeListTemplate.swift
Normal file
57
MVMCoreUI/Templates/MoleculeListTemplate.swift
Normal file
@ -0,0 +1,57 @@
|
||||
//
|
||||
// MoleculeListTemplate.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Scott Pfeil on 4/18/19.
|
||||
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import UIKit
|
||||
|
||||
public class MoleculeListTemplate: ThreeLayerTableViewController {
|
||||
|
||||
public override func registerWithTable() {
|
||||
super.registerWithTable()
|
||||
guard let molecules = loadObject?.pageJSON?.arrayForKey("molecules") else {
|
||||
return
|
||||
}
|
||||
for case let molecule as Dictionary<AnyHashable, Any> in molecules {
|
||||
if let moleculeName = molecule.optionalStringForKey("moleculeName") {
|
||||
tableView?.register(MoleculeTableViewCell.self, forCellReuseIdentifier: moleculeName)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override func viewForTop() -> UIView {
|
||||
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("header"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForJSON(moleculeJSON, delegateObject: delegateObject()) else {
|
||||
return super.viewForTop()
|
||||
}
|
||||
return molecule
|
||||
}
|
||||
|
||||
override public func viewForBottom() -> UIView {
|
||||
guard let moleculeJSON = loadObject?.pageJSON?.optionalDictionaryForKey("footer"), let molecule = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeForJSON(moleculeJSON, delegateObject: delegateObject()) else {
|
||||
return viewForBottom()
|
||||
}
|
||||
return molecule
|
||||
}
|
||||
|
||||
public override func newDataBuildScreen() {
|
||||
super.newDataBuildScreen()
|
||||
registerWithTable()
|
||||
}
|
||||
|
||||
public override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
|
||||
return loadObject?.pageJSON?.arrayForKey("molecules").count ?? 0
|
||||
}
|
||||
|
||||
public override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
|
||||
guard let molecule = loadObject?.pageJSON?.optionalDictionaryWithChainOfKeysOrIndexes(["molecules",indexPath.row]),
|
||||
let moleculeName = molecule.optionalStringForKey("moleculeName"),
|
||||
let cell = tableView.dequeueReusableCell(withIdentifier: moleculeName) as? MoleculeTableViewCell else {
|
||||
return UITableViewCell()
|
||||
}
|
||||
cell.setWithJSON(molecule, delegateObject: delegateObject(), additionalData: nil)
|
||||
return cell
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,7 @@ public class MoleculeStackTemplate: ThreeLayerViewController {
|
||||
|
||||
|
||||
public override func spaceBetweenTopAndMiddle() -> CGFloat? {
|
||||
return PaddingTwo
|
||||
return 0
|
||||
}
|
||||
|
||||
public override func viewForTop() -> UIView? {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user