diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 37c71b4f..22b92460 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -20,7 +20,7 @@ 01E569D3223FFFA500327251 /* ThreeLayerViewController.swift in Headers */ = {isa = PBXBuildFile; fileRef = D2A5146A2214905000345BFB /* ThreeLayerViewController.swift */; settings = {ATTRIBUTES = (Public, ); }; }; 0A1214A022C11A18007C7030 /* ActionDetailWithImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */; }; B8200E152280C4CF007245F4 /* ProgressBar.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8200E142280C4CF007245F4 /* ProgressBar.swift */; }; - B8200E192281DC1A007245F4 /* ProgressBarWithLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8200E182281DC1A007245F4 /* ProgressBarWithLabel.swift */; }; + B8200E192281DC1A007245F4 /* CornerLabels.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8200E182281DC1A007245F4 /* CornerLabels.swift */; }; D206997721FB8A0B00CAE0DE /* MVMCoreUINavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; }; D206997821FB8A0B00CAE0DE /* MVMCoreUINavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = D206997621FB8A0B00CAE0DE /* MVMCoreUINavigationController.m */; }; D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */; }; @@ -198,7 +198,7 @@ 01DF566F21FA5AB300CC099B /* TextFieldListFormViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TextFieldListFormViewController.swift; sourceTree = ""; }; 0A12149F22C11A17007C7030 /* ActionDetailWithImage.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActionDetailWithImage.swift; sourceTree = ""; }; B8200E142280C4CF007245F4 /* ProgressBar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBar.swift; sourceTree = ""; }; - B8200E182281DC1A007245F4 /* ProgressBarWithLabel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProgressBarWithLabel.swift; sourceTree = ""; }; + B8200E182281DC1A007245F4 /* CornerLabels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CornerLabels.swift; sourceTree = ""; }; D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUINavigationController.h; sourceTree = ""; }; D206997621FB8A0B00CAE0DE /* MVMCoreUINavigationController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUINavigationController.m; sourceTree = ""; }; D20A9A5D2243D3E300ADE781 /* TwoButtonView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TwoButtonView.swift; sourceTree = ""; }; @@ -492,7 +492,7 @@ D274CA322236A78900B01B62 /* StandardFooterView.swift */, D2E1FADC2268B25E00AEFD8C /* MoleculeTableViewCell.swift */, B8200E142280C4CF007245F4 /* ProgressBar.swift */, - B8200E182281DC1A007245F4 /* ProgressBarWithLabel.swift */, + B8200E182281DC1A007245F4 /* CornerLabels.swift */, D29B770F22C281F400D6ACE0 /* ModuleMolecule.swift */, D2A638FC22CA98280052ED1F /* HeadlineBody.swift */, D2A6390022CBB1820052ED1F /* Carousel.swift */, @@ -1019,7 +1019,7 @@ D2A514632213643100345BFB /* MoleculeStackCenteredTemplate.swift in Sources */, D29DF32421ED0DA2003B2FB9 /* TextButtonView.m in Sources */, D29DF29E21E7AE3B003B2FB9 /* MFStyler.m in Sources */, - B8200E192281DC1A007245F4 /* ProgressBarWithLabel.swift in Sources */, + B8200E192281DC1A007245F4 /* CornerLabels.swift in Sources */, D2A514592211C53C00345BFB /* MVMCoreUIMoleculeMappingObject.m in Sources */, 0105618D224BBE7700E1557D /* FormValidator.swift in Sources */, D22D1F1B220341F60077CEC0 /* MVMCoreUICheckBox.m in Sources */, diff --git a/MVMCoreUI/Atoms/Views/Label.swift b/MVMCoreUI/Atoms/Views/Label.swift index 53dd90e1..15ec60b2 100644 --- a/MVMCoreUI/Atoms/Views/Label.swift +++ b/MVMCoreUI/Atoms/Views/Label.swift @@ -198,7 +198,7 @@ public typealias ActionBlock = () -> () switch alignment { case "center": label.textAlignment = .center - case "trailing": + case "right": label.textAlignment = .right default: label.textAlignment = .left diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift index c0066afe..21802b38 100644 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift @@ -25,8 +25,8 @@ import UIKit var delegateObject: MVMCoreUIDelegateObject? // For keeping track of current state. - private var edges: UIRectEdge? - private var spinnerHeight: CGFloat? + private var edges = UIRectEdge(rawValue: 0) + private var spinnerHeight: CGFloat = 0 private var currentImageWidth: CGFloat? private var currentImageHeight: CGFloat? private var currentImageName: String? @@ -39,7 +39,6 @@ import UIKit // The default is an image that is centered with no edges pinned. So it will take the size of the content and fill as needed. public init() { - edges = UIRectEdge(rawValue: 0) super.init(frame: .zero) } @@ -93,10 +92,7 @@ import UIKit pinView(toSuperView: imageView) // Setup edges constraints - if edges == nil { - edges = UIRectEdge(rawValue: 0) - } - pinEdges(edges!) + pinEdges(edges) // Setup spinner. loadingSpinner.clipsToBounds = true @@ -185,7 +181,8 @@ import UIKit let widthWillChange = !MVMCoreGetterUtility.cgfequal(widthConstraint?.constant ?? 0, width ?? 0) let heightWillChange = !MVMCoreGetterUtility.cgfequal(heightConstraint?.constant ?? 0, height ?? 0) let sizeWillChange = (width == nil || height == nil) && !(size?.equalTo(imageView.image?.size ?? CGSize.zero) ?? false) - return widthWillChange || heightWillChange || sizeWillChange + let heightChangeFromSpinner = ((height ?? size?.height) ?? 0) < loadingSpinnerHeightConstraint?.constant ?? CGFloat.leastNormalMagnitude + return widthWillChange || heightWillChange || sizeWillChange || heightChangeFromSpinner } // Constrains the image view to be the size provided. Used to size it to the image to fix aspect fit defect. @@ -252,9 +249,9 @@ import UIKit self.currentImageName = imageName self.currentImageWidth = width?.cgfloat() self.currentImageHeight = height?.cgfloat() - self.loadingSpinner.resumeSpinnerAfterDelay() - if let height = self.spinnerHeight { - self.loadingSpinnerHeightConstraint?.constant = height + if MVMCoreCache.isHostedImage(imageName) { + self.loadingSpinner.resumeSpinnerAfterDelay() + self.loadingSpinnerHeightConstraint?.constant = self.spinnerHeight } let finishedLoadingBlock: MVMCoreGetImageBlock = {[weak self] (image, data, isFallbackImage) in MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in @@ -262,10 +259,10 @@ import UIKit return } self?.isFallbackImage = isFallbackImage - self?.loadingSpinnerHeightConstraint?.constant = 0 self?.loadingSpinner.pause() let layoutWillChange = self?.layoutWillChange(width: self?.currentImageWidth, height: self?.currentImageHeight, size: image?.size) ?? false self?.addConstraints(width: width, height: height, size: image?.size) + self?.loadingSpinnerHeightConstraint?.constant = 0 if layoutWillChange { self?.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated?(self!) } @@ -287,9 +284,8 @@ import UIKit MVMCoreDispatchUtility.performBlock(onMainThread: { [unowned self] in self.currentImageName = imageName self.loadingSpinner.resumeSpinnerAfterDelay() - if let height = self.spinnerHeight { - self.loadingSpinnerHeightConstraint?.constant = height - } + self.loadingSpinnerHeightConstraint?.constant = self.spinnerHeight + MVMCoreCache.shared()?.getCroppedImage(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, finalRect: cropRect, flipImage: flipImage, localFallbackImageName: customFallbackImage ?? MVMCoreUIUtility.localizedImageName("fallback"), completionHandler: { [weak self] (image, data, isFallBackImage) in MVMCoreDispatchUtility.performBlock(onMainThread: { guard let image = image, let loadingImageName = self?.currentImageName, loadingImageName == imageName else { diff --git a/MVMCoreUI/Atoms/Views/ViewConstrainingView.h b/MVMCoreUI/Atoms/Views/ViewConstrainingView.h index b07fd6bb..a5e359d0 100644 --- a/MVMCoreUI/Atoms/Views/ViewConstrainingView.h +++ b/MVMCoreUI/Atoms/Views/ViewConstrainingView.h @@ -73,6 +73,9 @@ // Add a view to be constrained in this view. - (void)addConstrainedView:(nonnull UIView *)view; +/// Can override to change how the molecule is added when shouldSetupMoleculeFromJSON = true. Inserts the molecule at 0 and calls pinToSuperView. +- (void)addMolecule:(nonnull UIView *)molecule; + // Change the alignment of the label - (void)alignLeft; - (void)alignCenterHorizontal; diff --git a/MVMCoreUI/Atoms/Views/ViewConstrainingView.m b/MVMCoreUI/Atoms/Views/ViewConstrainingView.m index dff48826..ba5f1bd0 100644 --- a/MVMCoreUI/Atoms/Views/ViewConstrainingView.m +++ b/MVMCoreUI/Atoms/Views/ViewConstrainingView.m @@ -241,6 +241,11 @@ } } +- (void)addMolecule:(nonnull UIView *)molecule { + [self insertSubview:molecule atIndex:0]; + [self pinViewToSuperView:molecule]; +} + #pragma mark - MVMCoreUIViewConstrainingProtocol - (void)alignHorizontal:(UIStackViewAlignment)alignment { @@ -352,17 +357,20 @@ [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; [self.molecule setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; - if (self.shouldSetupMoleculeFromJSON && !self.molecule) { + if (self.shouldSetupMoleculeFromJSON) { NSDictionary *moleculeJSON = [json dict:KeyMolecule]; - if (moleculeJSON) { + if (self.molecule) { + [self.molecule setWithJSON:moleculeJSON delegateObject:delegateObject additionalData:additionalData]; + } else if (moleculeJSON) { UIView *molecule = [[MVMCoreUIMoleculeMappingObject sharedMappingObject] createMoleculeForJSON:moleculeJSON delegateObject:delegateObject constrainIfNeeded:true]; if (molecule) { - [self insertSubview:molecule atIndex:0]; - [self pinViewToSuperView:molecule]; + [self addMolecule:molecule]; } self.molecule = molecule; + [self setMoleculeAccessibility]; } - [self setMoleculeAccessibility]; + } else { + [self.molecule setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; } NSNumber *useHorizontalMargins = [json optionalNumberForKey:@"useHorizontalMargins"]; diff --git a/MVMCoreUI/Molecules/CornerLabels.swift b/MVMCoreUI/Molecules/CornerLabels.swift new file mode 100644 index 00000000..06917608 --- /dev/null +++ b/MVMCoreUI/Molecules/CornerLabels.swift @@ -0,0 +1,180 @@ +// +// ProgressBarView.swift +// MVMCoreUI +// +// Created by Panth Patel on 5/3/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers public class CornerLabels: ViewConstrainingView { + + let topLeftLabel = Label.commonLabelB1(true) + let topRightLabel = Label.commonLabelB1(true) + let bottomLeftLabel = Label.commonLabelB3(true) + let bottomRightLabel = Label.commonLabelB3(true) + let topLabelsView = MVMCoreUICommonViewsUtility.commonView() + let bottomLabelsView = MVMCoreUICommonViewsUtility.commonView() + + /// The space between the molecule and top labels. Set to 0 if the top labels or molecule are not set. + var spaceAboveMolecule: CGFloat = 6.0 { + didSet { + if spaceAboveMolecule != oldValue { + topLabelToMoleculeConstraint?.constant = spaceAboveMolecule + } + } + } + + /// The space between the molecule and bottom labels. Set to 0 if the bottom labels or molecule are not set. + var spaceBelowMolecule: CGFloat = 6.0 { + didSet { + if spaceBelowMolecule != oldValue { + bottomLabelToMoleculeConstraint?.constant = spaceBelowMolecule + } + } + } + + var topLabelToMoleculeConstraint: NSLayoutConstraint? + var bottomLabelToMoleculeConstraint: NSLayoutConstraint? + + public override func addMolecule(_ molecule: UIView) { + insertSubview(molecule, at: 0) + topLabelToMoleculeConstraint?.isActive = false + bottomLabelToMoleculeConstraint?.isActive = false + + molecule.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor).isActive = true + layoutMarginsGuide.rightAnchor.constraint(equalTo: molecule.rightAnchor).isActive = true + + topLabelToMoleculeConstraint = molecule.topAnchor.constraint(equalTo: topLabelsView.bottomAnchor, constant: spaceAboveMolecule) + topLabelToMoleculeConstraint?.isActive = true + bottomLabelToMoleculeConstraint = bottomLabelsView.topAnchor.constraint(equalTo: molecule.bottomAnchor, constant: spaceBelowMolecule) + bottomLabelToMoleculeConstraint?.isActive = true + } + + // MARK: - MVMCoreViewProtocol + open override func updateView(_ size: CGFloat) { + super.updateView(size) + topLeftLabel.updateView(size) + topRightLabel.updateView(size) + bottomLeftLabel.updateView(size) + bottomRightLabel.updateView(size) + } + + public override func setupView() { + super.setupView() + shouldSetupMoleculeFromJSON = true + + guard topLeftLabel.superview == nil else { + return + } + + topRightLabel.textAlignment = .right + bottomRightLabel.textAlignment = .right + + addSubview(topLabelsView) + addSubview(bottomLabelsView) + topLabelsView.topAnchor.constraint(equalTo: layoutMarginsGuide.topAnchor).isActive = true + topLabelsView.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor).isActive = true + layoutMarginsGuide.rightAnchor.constraint(equalTo: topLabelsView.rightAnchor).isActive = true + + topLabelToMoleculeConstraint = bottomLabelsView.topAnchor.constraint(equalTo: topLabelsView.bottomAnchor, constant: 0) + topLabelToMoleculeConstraint?.isActive = true + bottomLabelToMoleculeConstraint = topLabelToMoleculeConstraint + + bottomLabelsView.leftAnchor.constraint(equalTo: layoutMarginsGuide.leftAnchor).isActive = true + layoutMarginsGuide.rightAnchor.constraint(equalTo: bottomLabelsView.rightAnchor).isActive = true + layoutMarginsGuide.bottomAnchor.constraint(equalTo: bottomLabelsView.bottomAnchor).isActive = true + + topLabelsView.addSubview(topLeftLabel) + topLabelsView.addSubview(topRightLabel) + setCompetitionConstraints(topLeftLabel,topRightLabel) + + bottomLabelsView.addSubview(bottomLeftLabel) + bottomLabelsView.addSubview(bottomRightLabel) + setCompetitionConstraints(bottomLeftLabel,bottomRightLabel) + + topLeftLabel.topAnchor.constraint(equalTo: topLabelsView.topAnchor).isActive = true + topLeftLabel.leftAnchor.constraint(equalTo: topLabelsView.leftAnchor).isActive = true + topLabelsView.bottomAnchor.constraint(greaterThanOrEqualTo: topLeftLabel.bottomAnchor).isActive = true + topRightLabel.topAnchor.constraint(equalTo: topLabelsView.topAnchor).isActive = true + topLabelsView.rightAnchor.constraint(equalTo: topRightLabel.rightAnchor).isActive = true + topLabelsView.bottomAnchor.constraint(greaterThanOrEqualTo: topRightLabel.bottomAnchor).isActive = true + + var constraint = topLabelsView.bottomAnchor.constraint(equalTo: topLeftLabel.bottomAnchor) + constraint.priority = topLeftLabel.contentHuggingPriority(for: .vertical) - 10 + constraint.isActive = true + + constraint = topLabelsView.bottomAnchor.constraint(equalTo: topRightLabel.bottomAnchor) + constraint.priority = topRightLabel.contentHuggingPriority(for: .vertical) - 10 + constraint.isActive = true + + topRightLabel.leftAnchor.constraint(equalTo: topLeftLabel.rightAnchor, constant: 16).isActive = true + + bottomLeftLabel.topAnchor.constraint(equalTo: bottomLabelsView.topAnchor).isActive = true + bottomLeftLabel.leftAnchor.constraint(equalTo: bottomLabelsView.leftAnchor).isActive = true + bottomLabelsView.bottomAnchor.constraint(greaterThanOrEqualTo: bottomLeftLabel.bottomAnchor).isActive = true + bottomRightLabel.topAnchor.constraint(equalTo: bottomLabelsView.topAnchor).isActive = true + bottomRightLabel.rightAnchor.constraint(equalTo: bottomLabelsView.rightAnchor).isActive = true + bottomLabelsView.bottomAnchor.constraint(greaterThanOrEqualTo: bottomRightLabel.bottomAnchor).isActive = true + + constraint = bottomLabelsView.bottomAnchor.constraint(equalTo: bottomLeftLabel.bottomAnchor) + constraint.priority = bottomLeftLabel.contentHuggingPriority(for: .vertical) - 10 + constraint.isActive = true + + constraint = bottomLabelsView.bottomAnchor.constraint(equalTo: bottomRightLabel.bottomAnchor) + constraint.priority = bottomRightLabel.contentHuggingPriority(for: .vertical) - 10 + constraint.isActive = true + + bottomRightLabel.leftAnchor.constraint(greaterThanOrEqualTo: bottomLeftLabel.rightAnchor, constant: 16).isActive = true + } + + /// Sets the rules for the labels if they were to collide. The first view will take priority, but the second view has a minimum width when competing. + func setCompetitionConstraints(_ view1: UIView,_ view2: UIView) { + view1.setContentHuggingPriority(UILayoutPriority(rawValue: 700), for: .horizontal) + view2.setContentHuggingPriority(UILayoutPriority(rawValue: 750), for: .horizontal) + view1.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 350), for: .horizontal) + view2.setContentCompressionResistancePriority(UILayoutPriority(rawValue: 300), for: .horizontal) + let width = view2.widthAnchor.constraint(equalTo: self.widthAnchor, multiplier: 0.40) + width.priority = UILayoutPriority(rawValue: 400) + width.isActive = true + } + + // MARK: - MVMCoreUIMoleculeViewProtocol + open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + topLeftLabel.setWithJSON(json?.optionalDictionaryForKey("topLeftLabel"), delegateObject: delegateObject, additionalData: additionalData) + topRightLabel.setWithJSON(json?.optionalDictionaryForKey("topRightLabel"), delegateObject: delegateObject, additionalData: additionalData) + bottomLeftLabel.setWithJSON(json?.optionalDictionaryForKey("bottomLeftLabel"), delegateObject: delegateObject, additionalData: additionalData) + bottomRightLabel.setWithJSON(json?.optionalDictionaryForKey("bottomRightLabel"), delegateObject: delegateObject, additionalData: additionalData) + + topLabelToMoleculeConstraint?.constant = (molecule != nil && (topLeftLabel.hasText || topRightLabel.hasText)) ? spaceAboveMolecule : 0 + bottomLabelToMoleculeConstraint?.constant = (molecule != nil && (bottomLeftLabel.hasText || bottomRightLabel.hasText)) ? spaceBelowMolecule : 0 + } + + public override func setAsMolecule() { + super.setAsMolecule() + styleDefault() + } + + public override func reset() { + super.reset() + + styleDefault() + spaceAboveMolecule = 6.0 + spaceBelowMolecule = 6.0 + + molecule?.reset?() + } + + func styleDefault() { + topLeftLabel.styleB1(true) + topRightLabel.styleB1(true) + bottomLeftLabel.styleB3(true) + bottomRightLabel.styleB3(true) + } + + public override static func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 34 + } +} diff --git a/MVMCoreUI/Molecules/MoleculeTableViewCell.swift b/MVMCoreUI/Molecules/MoleculeTableViewCell.swift index 00ea68ac..c1054e33 100644 --- a/MVMCoreUI/Molecules/MoleculeTableViewCell.swift +++ b/MVMCoreUI/Molecules/MoleculeTableViewCell.swift @@ -123,11 +123,6 @@ import UIKit contentView.addSubview(moleculeView) let standardConstraints = (moleculeView as? MVMCoreUIViewConstrainingProtocol)?.useStandardConstraints?() ?? true NSLayoutConstraint.activate(Array(NSLayoutConstraint.pinView(toSuperview: moleculeView, useMargins: standardConstraints).values)) - if standardConstraints { - let constraint = contentView.heightAnchor.constraint(equalToConstant: 80) - constraint.priority = .defaultLow - constraint.isActive = true - } molecule = moleculeView } } else { @@ -152,7 +147,7 @@ import UIKit guard let moleculeJSON = json?.optionalDictionaryForKey(KeyMolecule), let height = MVMCoreUIMoleculeMappingObject.shared()?.getMoleculeClass(withJSON: moleculeJSON)?.estimatedHeight?(forRow: moleculeJSON, delegateObject: delegateObject) else { return 80 } - return max(80, height) + return max(2 * PaddingDefaultVerticalSpacing3, height) } public static func name(forReuse molecule: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?) -> String? { diff --git a/MVMCoreUI/Molecules/ProgressBar.swift b/MVMCoreUI/Molecules/ProgressBar.swift index a9d7ad48..5416f0a7 100644 --- a/MVMCoreUI/Molecules/ProgressBar.swift +++ b/MVMCoreUI/Molecules/ProgressBar.swift @@ -8,41 +8,73 @@ import Foundation -public class ProgressBar: UIProgressView { - - var isRounded = Bool() - var thickness : Float = 0.0 { +@objcMembers open class ProgressBar: UIProgressView, MVMCoreUIMoleculeViewProtocol, MVMCoreViewProtocol { + var isRounded = false + var thickness: CGFloat = 8.0 { willSet(newValue) { - heightAnchor.constraint(equalToConstant: CGFloat(newValue)).isActive = true - switch isRounded { - case true: - layer.cornerRadius = CGFloat(newValue/2) - clipsToBounds = true - default: + heightAnchor.constraint(equalToConstant: newValue).isActive = true + if isRounded { + layer.cornerRadius = newValue/2.0 + } else { progressViewStyle = .bar } } } + public override init(frame: CGRect) { + super.init(frame: frame) + setupView() + } + + public required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + setupView() + } + + init() { + super.init(frame: .zero) + setupView() + } + + // MARK: - MVMCoreViewProtocol + public func setupView() { + clipsToBounds = true + translatesAutoresizingMaskIntoConstraints = false + reset() + } + + public func updateView(_ size: CGFloat) { + } + + // MARK: - MVMCoreUIMoleculeViewProtocol public func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { - isRounded = json?.optionalBoolForKey("roundedRect") ?? false - thickness = json?.floatFromStringForKey("thickness") ?? Float(0.0) - let percentage = json?.floatFromStringForKey("percent") - progress = (percentage ?? Float(0.0))/100 - progressTintColor = UIColor.mfBattleshipGrey() - trackTintColor = UIColor.mfLighterGray() - - if let progresscolor = json?.optionalStringForKey("progressColor") { - if !progresscolor.isEmpty { - progressTintColor = UIColor.mfGet(forHex: progresscolor) - } + if let isRounded = json?.optionalBoolForKey("roundedRect") { + self.isRounded = isRounded } - - if let backgroundcolor = json?.optionalStringForKey("backgroundColor") { - if !backgroundcolor.isEmpty { - trackTintColor = UIColor.mfGet(forHex: backgroundcolor) - } + if let thickness = json?.optionalCGFloatForKey("thickness") { + self.thickness = thickness } + if let percentage = json?["percent"] as? Float { + progress = percentage/100.0 + } + if let progressColor = json?.optionalStringForKey("progressColor") { + progressTintColor = UIColor.mfGet(forHex: progressColor) + } + if let backgroundColor = json?.optionalStringForKey("backgroundColor") { + trackTintColor = UIColor.mfGet(forHex: backgroundColor) + } + } + + public func reset() { + isRounded = false + thickness = 8 + progress = 0 + progressTintColor = UIColor.mfCerulean() + trackTintColor = UIColor.mfSilver() + } + + public static func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 8 } } diff --git a/MVMCoreUI/Molecules/ProgressBarWithLabel.swift b/MVMCoreUI/Molecules/ProgressBarWithLabel.swift deleted file mode 100644 index 9740e1ba..00000000 --- a/MVMCoreUI/Molecules/ProgressBarWithLabel.swift +++ /dev/null @@ -1,100 +0,0 @@ -// -// ProgressBarView.swift -// MVMCoreUI -// -// Created by Panth Patel on 5/3/19. -// Copyright © 2019 Verizon Wireless. All rights reserved. -// - -import UIKit - -@objcMembers public class ProgressBarWithLabel: ViewConstrainingView { - - var progress = ProgressBar() - var topleftlabel = Label() - var toprightlabel = Label() - var bottomleftlabel = Label() - var bottomrightlabel = Label() - - open override func needsToBeConstrained() -> Bool { - return true - } - - open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { - super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) - let progressbarjson = json?.optionalDictionaryForKey("progressbar") - progress.setWithJSON(progressbarjson, delegateObject: delegateObject, additionalData: additionalData) - - let topleftlabeljson = json?.optionalDictionaryForKey("label") - let toprightlabeljson = json?.optionalDictionaryForKey("toprightlabel") - let bottomleftlabeljson = json?.optionalDictionaryForKey("bottomleftlabel") - let bottomrightlabeljson = json?.optionalDictionaryForKey("bottomrightlabel") - - topleftlabel.setWithJSON(topleftlabeljson, delegateObject: delegateObject, additionalData: additionalData) - toprightlabel.setWithJSON(toprightlabeljson, delegateObject: delegateObject, additionalData: additionalData) - bottomleftlabel.setWithJSON(bottomleftlabeljson, delegateObject: delegateObject, additionalData: additionalData) - bottomrightlabel.setWithJSON(bottomrightlabeljson, delegateObject: delegateObject, additionalData: additionalData) - } - - override open func setupView() { - super.setupView() - addSubview(topleftlabel) - addSubview(toprightlabel) - addSubview(bottomleftlabel) - addSubview(bottomrightlabel) - addSubview(progress) - - progress.translatesAutoresizingMaskIntoConstraints = false - - topleftlabel.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true - topleftlabel.topAnchor.constraint(equalTo: self.topAnchor).isActive = true - let topleftwidthconstraint = NSLayoutConstraint(item: topleftlabel, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 0.5, constant: 0.0) - topleftwidthconstraint.priority = UILayoutPriority(100) - topleftwidthconstraint.isActive = true - topleftlabel.setContentHuggingPriority(UILayoutPriority(801), for: .horizontal) - topleftlabel.setContentHuggingPriority(UILayoutPriority(801), for: .vertical) - - NSLayoutConstraint(item: toprightlabel, attribute: .leading, relatedBy: .equal, toItem: topleftlabel, attribute: .trailing, multiplier: 1.0, constant: PaddingTwo).isActive = true - toprightlabel.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true - toprightlabel.topAnchor.constraint(equalTo: self.topAnchor).isActive = true - toprightlabel.textAlignment = .right - toprightlabel.setContentHuggingPriority(UILayoutPriority(802), for: .horizontal) - toprightlabel.setContentHuggingPriority(UILayoutPriority(802), for: .vertical) - - var topconstraint = progress.topAnchor.constraint(equalTo: topleftlabel.bottomAnchor, constant: PaddingTwo) - topconstraint.priority = UILayoutPriority(249) - topconstraint.isActive = true - progress.topAnchor.constraint(greaterThanOrEqualTo: topleftlabel.bottomAnchor, constant: PaddingTwo).isActive = true - topconstraint = progress.topAnchor.constraint(equalTo: toprightlabel.bottomAnchor, constant: PaddingTwo) - topconstraint.priority = UILayoutPriority(249) - topconstraint.isActive = true - progress.topAnchor.constraint(greaterThanOrEqualTo: toprightlabel.bottomAnchor, constant: PaddingTwo).isActive = true - - progress.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true - progress.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true - - bottomleftlabel.topAnchor.constraint(equalTo: progress.bottomAnchor, constant: PaddingTwo).isActive = true - bottomleftlabel.leftAnchor.constraint(equalTo: self.leftAnchor).isActive = true - let bottomleftwidthconstraint = NSLayoutConstraint(item: bottomleftlabel, attribute: .width, relatedBy: .equal, toItem: self, attribute: .width, multiplier: 0.5, constant: 0.0) - bottomleftwidthconstraint.priority = UILayoutPriority(100) - bottomleftwidthconstraint.isActive = true - bottomleftlabel.setContentHuggingPriority(UILayoutPriority(801), for: .horizontal) - bottomleftlabel.setContentHuggingPriority(UILayoutPriority(801), for: .vertical) - - NSLayoutConstraint(item: bottomrightlabel, attribute: .leading, relatedBy: .equal, toItem: bottomleftlabel, attribute: .trailing, multiplier: 1.0, constant: PaddingTwo).isActive = true - bottomrightlabel.topAnchor.constraint(equalTo: progress.bottomAnchor, constant: PaddingTwo).isActive = true - bottomrightlabel.rightAnchor.constraint(equalTo: self.rightAnchor).isActive = true - bottomrightlabel.textAlignment = .right - bottomrightlabel.setContentHuggingPriority(UILayoutPriority(802), for: .horizontal) - bottomrightlabel.setContentHuggingPriority(UILayoutPriority(802), for: .vertical) - - var bottomconstraint = bottomAnchor.constraint(equalTo: bottomleftlabel.bottomAnchor, constant: PaddingTwo) - bottomconstraint.priority = UILayoutPriority(249) - bottomconstraint.isActive = true - bottomAnchor.constraint(greaterThanOrEqualTo: bottomleftlabel.bottomAnchor, constant: PaddingTwo).isActive = true - bottomconstraint = bottomAnchor.constraint(equalTo: bottomrightlabel.bottomAnchor, constant: PaddingTwo) - bottomconstraint.priority = UILayoutPriority(249) - bottomconstraint.isActive = true - bottomAnchor.constraint(greaterThanOrEqualTo: bottomrightlabel.bottomAnchor, constant: PaddingTwo).isActive = true - } -} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index cd829697..0dffc356 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -39,7 +39,7 @@ @"textField" : MFTextField.class, @"digitTextField" : MFDigitTextField.class, @"checkbox" : MVMCoreUICheckBox.class, - @"progressBarWithLabel" : ProgressBarWithLabel.class, + @"cornerLabels" : CornerLabels.class, @"progressBar": ProgressBar.class, @"textField": MFTextField.class, @"checkbox": MVMCoreUICheckBox.class, diff --git a/MVMCoreUI/Styles/MFStyler.h b/MVMCoreUI/Styles/MFStyler.h index bda6c112..2ab3c2f2 100644 --- a/MVMCoreUI/Styles/MFStyler.h +++ b/MVMCoreUI/Styles/MFStyler.h @@ -29,6 +29,7 @@ typedef NS_ENUM(NSUInteger, MFTimeFormatUnit) { extern CGFloat const PaddingDefault; extern CGFloat const PaddingDefaultHorizontalSpacing; extern CGFloat const PaddingDefaultVerticalSpacing; +extern CGFloat const PaddingDefaultVerticalSpacing3; extern CGFloat const PaddingBetweenFields; extern CGFloat const PaddingHorizontalHeadlineWhiteView; extern CGFloat const PaddingHorizontalLarge; diff --git a/MVMCoreUI/Styles/MFStyler.m b/MVMCoreUI/Styles/MFStyler.m index 2b0d0a0a..dfc9909a 100644 --- a/MVMCoreUI/Styles/MFStyler.m +++ b/MVMCoreUI/Styles/MFStyler.m @@ -18,6 +18,7 @@ CGFloat const PaddingDefault = 24; CGFloat const PaddingDefaultHorizontalSpacing = 32; CGFloat const PaddingDefaultVerticalSpacing = 32; +CGFloat const PaddingDefaultVerticalSpacing3 = 24; CGFloat const PaddingBetweenFields = 24; CGFloat const PaddingHorizontalHeadlineWhiteView = 60; CGFloat const PaddingHorizontalLarge = 72; @@ -97,7 +98,7 @@ CGFloat const LabelWithInternalButtonLineSpace = 2; + (void)setDefaultMarginsForView:(nullable UIView *)view size:(CGFloat)size horizontal:(BOOL)horizontal vertical:(BOOL)vertical { [MVMCoreDispatchUtility performBlockOnMainThread:^{ CGFloat horizontalPadding = horizontal ? [MFStyler defaultHorizontalPaddingForSize:size] : 0; - CGFloat verticalPadding = vertical ? PaddingDefaultVerticalSpacing : 0; + CGFloat verticalPadding = vertical ? PaddingDefaultVerticalSpacing3 : 0; [MVMCoreUIUtility setMarginsForView:view leading:horizontalPadding top:verticalPadding trailing:horizontalPadding bottom:verticalPadding]; }]; }