diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 1a84907a..752a5445 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -106,6 +106,10 @@ 9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; }; 946EE1BA237B66D80036751F /* MoleculeModelHelper.swift in Sources */ = {isa = PBXBuildFile; fileRef = 946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */; }; 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; }; + 94AF4A3E23E9D13900676048 /* MFCaretButton.h in Headers */ = {isa = PBXBuildFile; fileRef = 94AF4A3C23E9D13900676048 /* MFCaretButton.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 94AF4A3D23E9D13900676048 /* MFCaretButton.m */; }; + 94AF4A4223E9D19E00676048 /* MFCaretView.h in Headers */ = {isa = PBXBuildFile; fileRef = 94AF4A4023E9D19E00676048 /* MFCaretView.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */ = {isa = PBXBuildFile; fileRef = 94AF4A4123E9D19E00676048 /* MFCaretView.m */; }; 94C2D9842386F3F80006CF46 /* LabelAttributeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9832386F3F80006CF46 /* LabelAttributeModel.swift */; }; 94C2D9A123872BCC0006CF46 /* LabelAttributeUnderlineModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A023872BCC0006CF46 /* LabelAttributeUnderlineModel.swift */; }; 94C2D9A323872C110006CF46 /* LabelAttributeStrikeThroughModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C2D9A223872C110006CF46 /* LabelAttributeStrikeThroughModel.swift */; }; @@ -420,6 +424,10 @@ 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = ""; }; 946EE1B9237B66D80036751F /* MoleculeModelHelper.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeModelHelper.swift; sourceTree = ""; }; 948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = ""; }; + 94AF4A3C23E9D13900676048 /* MFCaretButton.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MFCaretButton.h; sourceTree = ""; }; + 94AF4A3D23E9D13900676048 /* MFCaretButton.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MFCaretButton.m; sourceTree = ""; }; + 94AF4A4023E9D19E00676048 /* MFCaretView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MFCaretView.h; sourceTree = ""; }; + 94AF4A4123E9D19E00676048 /* MFCaretView.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MFCaretView.m; sourceTree = ""; }; 94C2D9832386F3F80006CF46 /* LabelAttributeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeModel.swift; sourceTree = ""; }; 94C2D9A023872BCC0006CF46 /* LabelAttributeUnderlineModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeUnderlineModel.swift; sourceTree = ""; }; 94C2D9A223872C110006CF46 /* LabelAttributeStrikeThroughModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LabelAttributeStrikeThroughModel.swift; sourceTree = ""; }; @@ -830,6 +838,10 @@ 94F217B423E0BF6100A47C06 /* PrimaryButtonView.h */, 94F217B523E0BF6100A47C06 /* PrimaryButtonView.m */, D282AACA2243C61700C46919 /* ButtonView.swift */, + 94AF4A3C23E9D13900676048 /* MFCaretButton.h */, + 94AF4A3D23E9D13900676048 /* MFCaretButton.m */, + 94AF4A4023E9D19E00676048 /* MFCaretView.h */, + 94AF4A4123E9D19E00676048 /* MFCaretView.m */, ); path = Views; sourceTree = ""; @@ -1408,6 +1420,7 @@ D29DF27521E79E81003B2FB9 /* MVMCoreUILoggingHandler.h in Headers */, D29DF28B21E7AC2B003B2FB9 /* ViewConstrainingView.h in Headers */, D29DF2B321E7B76D003B2FB9 /* MFLoadingSpinner.h in Headers */, + 94AF4A3E23E9D13900676048 /* MFCaretButton.h in Headers */, 0A21DB8A235E06EF00C160A2 /* MFDigitTextBox.h in Headers */, D29DF32521ED0DA2003B2FB9 /* TextButtonView.h in Headers */, 0A21DB8C235E06EF00C160A2 /* MFDigitTextField.h in Headers */, @@ -1426,6 +1439,7 @@ D29DF2CA21E7BFC8003B2FB9 /* MFSizeThreshold.h in Headers */, D29DF28021E7AA51003B2FB9 /* MVMCoreUIDetailViewProtocol.h in Headers */, D29DF2BD21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.h in Headers */, + 94AF4A4223E9D19E00676048 /* MFCaretView.h in Headers */, D29DF2EE21ECEADF003B2FB9 /* MFFonts.h in Headers */, D29DF12D21E6851E003B2FB9 /* MVMCoreUITopAlertBaseView.h in Headers */, D29770F321F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.h in Headers */, @@ -1671,6 +1685,7 @@ 944589212385D6E900DE9FD4 /* DashLineModel.swift in Sources */, D2E2A99623D8CF85000B42E6 /* HeadlineBodyLinkToggleModel.swift in Sources */, C6FA7D5323C77A4A00A3614A /* StringAndMoleculeStack.swift in Sources */, + 94AF4A3F23E9D13900676048 /* MFCaretButton.m in Sources */, D29DF27A21E7A533003B2FB9 /* MVMCoreUISession.m in Sources */, D2A5146B2214905000345BFB /* ThreeLayerViewController.swift in Sources */, D28A838F23CCDEDE00DFE4FC /* TwoButtonViewModel.swift in Sources */, @@ -1720,6 +1735,7 @@ D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */, 0A21DB94235E24ED00C160A2 /* DigitEntryField.swift in Sources */, 0A21DB8D235E06EF00C160A2 /* MFDigitTextField.m in Sources */, + 94AF4A4323E9D19E00676048 /* MFCaretView.m in Sources */, 943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */, D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */, 948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */, diff --git a/MVMCoreUI/Atoms/Buttons/CaretButton.swift b/MVMCoreUI/Atoms/Buttons/CaretButton.swift index 97f8d55e..405e110f 100644 --- a/MVMCoreUI/Atoms/Buttons/CaretButton.swift +++ b/MVMCoreUI/Atoms/Buttons/CaretButton.swift @@ -63,10 +63,18 @@ open class CaretButton: Button, MVMCoreUIViewConstrainingProtocol { setTitleColor(disabledColor, for: .disabled) if let rightCaretView = rightView as? CaretView { + rightCaretView.enabledColor = enabledColor + rightCaretView.disabledColor = disabledColor rightCaretView.isEnabled = isEnabled } } + private func createCaretView() -> CaretView { + let caret = CaretView() + caret.lineWidth = 1.5 + return caret + } + private func addCaretImageView() { rightView?.removeFromSuperview() @@ -77,7 +85,7 @@ open class CaretButton: Button, MVMCoreUIViewConstrainingProtocol { let edgeInsets: UIEdgeInsets = contentEdgeInsets contentEdgeInsets = UIEdgeInsets(top: edgeInsets.top, left: edgeInsets.left, bottom: edgeInsets.bottom, right: 4 + width) - let caretView: UIView = rightView ?? CaretView() + let caretView: UIView = rightView ?? createCaretView() rightView = caretView rightView?.translatesAutoresizingMaskIntoConstraints = false addSubview(caretView) diff --git a/MVMCoreUI/Atoms/Views/MultiProgress.swift b/MVMCoreUI/Atoms/Views/MultiProgress.swift index cee425cc..cd05ed0b 100644 --- a/MVMCoreUI/Atoms/Views/MultiProgress.swift +++ b/MVMCoreUI/Atoms/Views/MultiProgress.swift @@ -31,7 +31,7 @@ import UIKit view.translatesAutoresizingMaskIntoConstraints = false addSubview(view) view.backgroundColor = progressObject.progressColor.uiColor - view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: progressObject.progress).isActive = true + view.widthAnchor.constraint(equalTo: widthAnchor, multiplier: progressObject.progress/100.0).isActive = true view.leadingAnchor.constraint(equalTo: previous?.trailingAnchor ?? leadingAnchor).isActive = true previous = view NSLayoutConstraint.constraintPinSubview(view, pinTop: true, pinBottom: true, pinLeft: false, pinRight: false) diff --git a/MVMCoreUI/Legacy/Views/MFCaretButton.h b/MVMCoreUI/Legacy/Views/MFCaretButton.h new file mode 100644 index 00000000..c6426e35 --- /dev/null +++ b/MVMCoreUI/Legacy/Views/MFCaretButton.h @@ -0,0 +1,26 @@ +// +// MFCaretButton.h +// MobileFirstFramework +// +// Created by Kolli, Praneeth on 1/5/18. +// Copyright © 2018 Verizon Wireless. All rights reserved. +// + +#import +#import + +@interface MFCaretButton : MFCustomButton + +@property (nullable, nonatomic, strong) UIView *rightView; +@property (nullable, nonatomic, strong) NSNumber *rightViewHeight; +@property (nullable, nonatomic, strong) NSNumber *rightViewWidth; + +-(void)updateCaretSpacing:(CGFloat)spacing; + +/* The fill color of the Caret and titleLabel. The default is blackColor */ +-(void)setEnableCaretColor:(nullable UIColor *)enableCaretColor; + +/* The fill color of the Caret and titleLabel. The default is mfSilver */ +-(void)setDisabledCaretColor:(nullable UIColor *)disabledCaretColor; + +@end diff --git a/MVMCoreUI/Legacy/Views/MFCaretButton.m b/MVMCoreUI/Legacy/Views/MFCaretButton.m new file mode 100644 index 00000000..bd8f058c --- /dev/null +++ b/MVMCoreUI/Legacy/Views/MFCaretButton.m @@ -0,0 +1,113 @@ +// +// MFCaretButton.m +// MobileFirstFramework +// +// Created by Kolli, Praneeth on 1/5/18. +// Copyright © 2018 Verizon Wireless. All rights reserved. +// + +#import "MFCaretButton.h" +#import "MFCaretView.h" +#import "UIColor+MFConvenience.h" + +@interface MFCaretButton () + +@property (nonatomic, strong) UIColor *enableColor; +@property (nonatomic, strong) UIColor *disabledColor; +@property (nonatomic, strong) NSLayoutConstraint *caretSpacingConstraint; + +@end + +@implementation MFCaretButton + +CGFloat const CaretViewHeight = 10.8f; +CGFloat const CaretViewWidth = 6.6f; + + +- (void)layoutSubviews { + [self addCaretImageView]; + [super layoutSubviews]; +} + +- (void)setEnabled:(BOOL)enabled { + [super setEnabled:enabled]; + [self changeCaretColor]; +} +- (void)changeCaretColor { + [self setTitleColor:self.enableColor forState:UIControlStateNormal]; + [self setTitleColor:self.disabledColor forState:UIControlStateDisabled]; + if ([self.rightView isKindOfClass:[MFCaretView class]]) { + MFCaretView *caretView = (MFCaretView *)self.rightView; + if (self.enabled) { + [caretView setLineColor:self.enableColor]; + } else { + [caretView setLineColor:self.disabledColor]; + } + } +} + +- (void)addCaretImageView { + [self.rightView removeFromSuperview]; + UIEdgeInsets edgeInsets = self.contentEdgeInsets; + CGFloat rightInset = self.rightViewWidth?self.rightViewWidth.floatValue:CaretViewWidth; + UIEdgeInsets newInsets = UIEdgeInsetsMake(edgeInsets.top, edgeInsets.left, edgeInsets.bottom, 4 + rightInset); + self.contentEdgeInsets = newInsets; + UIView *caretViewIs = self.rightView; + if (!self.rightView) { + caretViewIs = [[MFCaretView alloc]init]; + self.rightView = caretViewIs; + } + self.rightView.translatesAutoresizingMaskIntoConstraints = NO; + [self addSubview:self.rightView]; + + CGFloat width = self.rightViewWidth?self.rightViewWidth.floatValue:CaretViewWidth; + NSLayoutConstraint *caretViewWidthConstraint = [NSLayoutConstraint constraintWithItem:caretViewIs attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:width]; + caretViewWidthConstraint.active = YES; + + CGFloat height = self.rightViewHeight?self.rightViewHeight.floatValue:CaretViewHeight; + NSLayoutConstraint *caretViewHeightConstraint = [NSLayoutConstraint constraintWithItem:caretViewIs attribute:NSLayoutAttributeHeight relatedBy:NSLayoutRelationEqual toItem:nil attribute:NSLayoutAttributeNotAnAttribute multiplier:1.0 constant:height]; + caretViewHeightConstraint.active = YES; + + NSLayoutConstraint *caretLabelSpacing = [NSLayoutConstraint constraintWithItem:caretViewIs attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self.titleLabel attribute:NSLayoutAttributeRight multiplier:1.0 constant:4.0]; + caretLabelSpacing.active = YES; + self.caretSpacingConstraint = caretLabelSpacing; + + NSLayoutConstraint *caretCenterY = [NSLayoutConstraint constraintWithItem:caretViewIs attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]; + caretCenterY.active = YES; + + NSLayoutConstraint *caretLabelRightPin = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationGreaterThanOrEqual toItem:caretViewIs attribute:NSLayoutAttributeRight multiplier:1.0 constant:0]; + caretLabelRightPin.active = YES; + self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + //set correct color after layout + [self changeCaretColor]; +} +- (void)updateCaretSpacing:(CGFloat)spacing { + if (self.caretSpacingConstraint != nil) { + self.caretSpacingConstraint.constant = spacing; + } +} +- (void)setEnableCaretColor:(UIColor *)enableCaretColor { + self.enableColor = enableCaretColor; + [self changeCaretColor]; +} +- (void)setDisabledCaretColor:(UIColor *)disabledCaretColor { + self.disabledColor = disabledCaretColor; + [self changeCaretColor]; +} +@synthesize enableColor = _enableColor; +- (UIColor *)enableColor { + if (!_enableColor) { + _enableColor = [UIColor blackColor]; + } + return _enableColor; +} + +@synthesize disabledColor = _disabledColor; +- (UIColor *)disabledColor { + if (!_disabledColor) { + _disabledColor = [UIColor mfSilver]; + } + return _disabledColor; +} + +@end diff --git a/MVMCoreUI/Legacy/Views/MFCaretView.h b/MVMCoreUI/Legacy/Views/MFCaretView.h new file mode 100644 index 00000000..e2053f9a --- /dev/null +++ b/MVMCoreUI/Legacy/Views/MFCaretView.h @@ -0,0 +1,16 @@ +// +// MFCaretView.h +// MobileFirstFramework +// +// Created by Kolli, Praneeth on 1/5/18. +// Copyright © 2018 Verizon Wireless. All rights reserved. +// + +#import + +@interface MFCaretView : UIView +@property (strong, nonatomic, readonly) UIColor *strokeColor; +- (instancetype)initWithLineWidth:(CGFloat)lineWidth; +- (void)setLineColor:(UIColor *)color; +@end + diff --git a/MVMCoreUI/Legacy/Views/MFCaretView.m b/MVMCoreUI/Legacy/Views/MFCaretView.m new file mode 100644 index 00000000..182f7a74 --- /dev/null +++ b/MVMCoreUI/Legacy/Views/MFCaretView.m @@ -0,0 +1,93 @@ +// +// MFCaretView.m +// MobileFirstFramework +// +// Created by Kolli, Praneeth on 1/5/18. +// Copyright © 2018 Verizon Wireless. All rights reserved. +// + +#import "MFCaretView.h" +#import "UIColor+MFConvenience.h" +@interface MFCaretView () +@property (strong, nonatomic, readwrite) UIColor *strokeColor; +@property (nonatomic) NSNumber *lineWidth; + +@end + +@implementation MFCaretView + +- (instancetype)init { + self = [super init]; + if (self) { + // Initialization code + self.opaque = NO; + self.backgroundColor = [UIColor clearColor]; + self.strokeColor = [UIColor blackColor]; + } + return self; +} + +- (instancetype)initWithFrame:(CGRect)frame { + self = [super initWithFrame:frame]; + if (self) { + // Initialization code + self.opaque = NO; + self.backgroundColor = [UIColor clearColor]; + self.strokeColor = [UIColor blackColor]; + } + return self; +} + +- (instancetype)initWithCoder:(NSCoder *)aDecoder { + self = [super initWithCoder:aDecoder]; + if (self) { + // Initialization code + self.opaque = NO; + self.backgroundColor = [UIColor clearColor]; + self.strokeColor = [UIColor blackColor]; + } + return self; +} + +- (instancetype)initWithLineWidth:(CGFloat)lineWidth { + if (self = [super init]) { + self.opaque = NO; + self.backgroundColor = [UIColor clearColor]; + self.lineWidth = @(lineWidth); + self.strokeColor = [UIColor blackColor]; + } + return self; +} + +- (void)drawRect:(CGRect)rect { + // Drawing Caret + CGContextRef context = UIGraphicsGetCurrentContext(); + CGContextClearRect(context, rect); + + CGFloat lineWidth; + if (self.lineWidth) { + lineWidth = self.lineWidth.floatValue; + } else { + lineWidth = self.frame.size.width/2.6; + } + + UIBezierPath *path = [[UIBezierPath alloc] init]; + [path moveToPoint:CGPointMake(lineWidth/2.0, 0.0)]; + [path addLineToPoint:CGPointMake(self.frame.size.width, self.frame.size.height/2.0)]; + [path addLineToPoint:CGPointMake(lineWidth/2.0, self.frame.size.height)]; + [path addLineToPoint:CGPointMake(0.0, self.frame.size.height-lineWidth/2.0)]; + [path addLineToPoint:CGPointMake(self.frame.size.width-lineWidth, self.frame.size.height/2.0)]; + [path addLineToPoint:CGPointMake(0.0, lineWidth/2.0)]; + [path addLineToPoint:CGPointMake(lineWidth/2.0, 0.0)]; + [self.strokeColor setFill]; + [path fill]; + [path closePath]; + [self setBackgroundColor:[UIColor clearColor]]; +} + +- (void)setLineColor:(UIColor *)color { + self.strokeColor = color; + [self setNeedsDisplay]; +} + +@end diff --git a/MVMCoreUI/MVMCoreUI.h b/MVMCoreUI/MVMCoreUI.h index 9150e015..1b2183aa 100644 --- a/MVMCoreUI/MVMCoreUI.h +++ b/MVMCoreUI/MVMCoreUI.h @@ -81,6 +81,7 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[]; #import #import #import +#import #pragma mark Buttons #import @@ -89,6 +90,7 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[]; #import #import #import +#import #pragma mark TextFields #import diff --git a/MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift b/MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift index 680e7089..2de9deca 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/CornerLabels.swift @@ -171,10 +171,8 @@ import UIKit guard let model = model as? CornerLabelsModel else { return } if middleView != nil { (middleView as? ModelMoleculeViewProtocol)?.setWithModel(model, delegateObject, additionalData) - } else { - if let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(model.molecule, delegateObject) { - addMiddleView(molecule) - } + } else if let moleculeModel = model.molecule, let molecule = MVMCoreUIMoleculeMappingObject.shared()?.createMolecule(moleculeModel, delegateObject) { + addMiddleView(molecule) } topLeftLabel.setWithModel(model.topLeftLabel, delegateObject, additionalData) diff --git a/MVMCoreUI/Molecules/LeftRightViews/CornerLabelsModel.swift b/MVMCoreUI/Molecules/LeftRightViews/CornerLabelsModel.swift index ce3796bf..f4b67216 100644 --- a/MVMCoreUI/Molecules/LeftRightViews/CornerLabelsModel.swift +++ b/MVMCoreUI/Molecules/LeftRightViews/CornerLabelsModel.swift @@ -15,9 +15,9 @@ public class CornerLabelsModel: MoleculeModelProtocol { public var topRightLabel: LabelModel? public var bottomLeftLabel: LabelModel? public var bottomRightLabel: LabelModel? - public var molecule: MoleculeModelProtocol + public var molecule: MoleculeModelProtocol? - init(with molecule: MoleculeModelProtocol) { + init(with molecule: MoleculeModelProtocol?) { self.molecule = molecule } @@ -33,7 +33,7 @@ public class CornerLabelsModel: MoleculeModelProtocol { required public init(from decoder: Decoder) throws { let typeContainer = try decoder.container(keyedBy: CodingKeys.self) backgroundColor = try typeContainer.decodeIfPresent(Color.self, forKey: .backgroundColor) - molecule = try typeContainer.decodeMolecule(codingKey: .molecule) + molecule = try typeContainer.decodeMoleculeIfPresent(codingKey: .molecule) topLeftLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .topLeftLabel) topRightLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .topRightLabel) bottomLeftLabel = try typeContainer.decodeIfPresent(LabelModel.self, forKey: .bottomLeftLabel) diff --git a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift index fc19749a..d5abe33f 100644 --- a/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift +++ b/MVMCoreUI/Molecules/VerticalCombinationViews/HeadLineBodyCaretLinkImage.swift @@ -11,7 +11,6 @@ import Foundation let headlineBody = HeadlineBody(frame: .zero) let caretButton = CaretButton(frame: .zero) let backgroundImageView = MFLoadImageView(pinnedEdges: .all) - var spaceBetweenConstant: CGFloat = 104.0 let maxWidth: CGFloat = 350.0 static let heightConstant: CGFloat = 320.0 var heightConstraint: NSLayoutConstraint? @@ -44,17 +43,17 @@ import Foundation headlineBody.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true headlineBody.topAnchor.constraint(equalTo: container.topAnchor, constant: 0).isActive = true - let headLineBodyWidth = headlineBody.widthAnchor.constraint(equalTo: container.widthAnchor, multiplier: 0.85) - headLineBodyWidth.priority = .defaultHigh + headlineBody.widthAnchor.constraint(equalTo: container.widthAnchor, multiplier: 0.67).isActive = true + let headLineBodyWidth = headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: maxWidth) + headLineBodyWidth.priority = UILayoutPriority(250) headLineBodyWidth.isActive = true - headlineBody.widthAnchor.constraint(lessThanOrEqualToConstant: maxWidth).isActive = true //Caret view caretButton.translatesAutoresizingMaskIntoConstraints = false caretButton.leadingAnchor.constraint(equalTo: container.leadingAnchor, constant: 0).isActive = true container.bottomAnchor.constraint(equalTo: caretButton.bottomAnchor, constant: 0).isActive = true - caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: spaceBetweenConstant).isActive = true + caretButton.topAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor, constant: PaddingTwo).isActive = true //Background image view backgroundImageView.translatesAutoresizingMaskIntoConstraints = false diff --git a/MVMCoreUI/Organisms/Stack.swift b/MVMCoreUI/Organisms/Stack.swift index 2ab77421..4e7a3114 100644 --- a/MVMCoreUI/Organisms/Stack.swift +++ b/MVMCoreUI/Organisms/Stack.swift @@ -33,8 +33,9 @@ open class Stack: Container where T: StackModelProtocol { }) // Adds the views + let totalSpace = getTotalSpace() for (index, view) in stackItems.enumerated() { - addView(view, stackModel.molecules[index], percentModifier: getPercentModifier(), lastItem: lastItemIndex == index) + addView(view, stackModel.molecules[index], totalSpacing: totalSpace, lastItem: lastItemIndex == index) } } @@ -173,14 +174,12 @@ open class Stack: Container where T: StackModelProtocol { // MARK: - Adding to stack /// Gets the percent modifier. This value is used to help properly calculate percent for stack items when spacing is involved. - private func getPercentModifier() -> CGFloat { + private func getTotalSpace() -> CGFloat { guard let stackModel = stackModel else { return 0.0 } var totalSpace: CGFloat = 0.0 - var totalViews = 0 var firstMoleculeFound = false for stackItemModel in stackModel.molecules { guard !stackItemModel.gone else { continue } - totalViews += 1 let spacing = stackItemModel.spacing ?? stackModel.spacing if firstMoleculeFound { totalSpace += spacing @@ -189,11 +188,11 @@ open class Stack: Container where T: StackModelProtocol { totalSpace += (stackModel.useStackSpacingBeforeFirstItem ? spacing : stackItemModel.spacing ?? 0) } } - return (totalViews > 0 ? -(totalSpace / CGFloat(totalViews)) : 0) + return totalSpace } /// Adds the stack item view - private func addView(_ view: UIView,_ model: StackItemModelProtocol, percentModifier: CGFloat, lastItem: Bool) { + private func addView(_ view: UIView,_ model: StackItemModelProtocol, totalSpacing: CGFloat, lastItem: Bool) { guard let stackModel = self.stackModel else { return } guard !model.gone else { // Gone views do not show @@ -223,7 +222,9 @@ open class Stack: Container where T: StackModelProtocol { pinView(view, toView: contentView, attribute: .leading, relation: .equal, priority: .required, constant: 0) pinView(contentView, toView: view, attribute: .trailing, relation: .equal, priority: .required, constant: 0) if let percent = model.percent { - view.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: CGFloat(percent)/100.0, constant: percentModifier).isActive = true + let multiplier = CGFloat(percent)/100.0 + let constant = multiplier * totalSpacing + view.heightAnchor.constraint(equalTo: contentView.heightAnchor, multiplier: multiplier, constant: -constant).isActive = true } if lastItem { pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0) @@ -240,7 +241,9 @@ open class Stack: Container where T: StackModelProtocol { pinView(view, toView: contentView, attribute: .top, relation: .equal, priority: .required, constant: 0) pinView(contentView, toView: view, attribute: .bottom, relation: .equal, priority: .required, constant: 0) if let percent = model.percent { - view.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: CGFloat(percent)/100.0, constant: percentModifier).isActive = true + let multiplier = CGFloat(percent)/100.0 + let constant = multiplier * totalSpacing + view.widthAnchor.constraint(equalTo: contentView.widthAnchor, multiplier: multiplier, constant: -constant).isActive = true } if lastItem { pinView(contentView, toView: view, attribute: .right, relation: .equal, priority: .required, constant: 0)