diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index 920b1d72..b4295986 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -167,6 +167,7 @@ D2A638FD22CA98280052ED1F /* HeadlineBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A638FC22CA98280052ED1F /* HeadlineBody.swift */; }; D2A6390122CBB1820052ED1F /* Carousel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A6390022CBB1820052ED1F /* Carousel.swift */; }; D2A6390522CBCE160052ED1F /* MoleculeCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2A6390422CBCE160052ED1F /* MoleculeCollectionViewCell.swift */; }; + D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2B1E3E422F37D6A0065F95C /* ImageHeadlineBody.swift */; }; D2C5001821F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; D2C5001921F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */; }; D2D6CD4022E78C1A00D701B8 /* Scroller.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */; }; @@ -347,6 +348,7 @@ D2A638FC22CA98280052ED1F /* HeadlineBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBody.swift; sourceTree = ""; }; D2A6390022CBB1820052ED1F /* Carousel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Carousel.swift; sourceTree = ""; }; D2A6390422CBCE160052ED1F /* MoleculeCollectionViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MoleculeCollectionViewCell.swift; sourceTree = ""; }; + D2B1E3E422F37D6A0065F95C /* ImageHeadlineBody.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageHeadlineBody.swift; sourceTree = ""; }; D2C5001621F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIViewControllerMappingObject.h; sourceTree = ""; }; D2C5001721F8ECDD001DA659 /* MVMCoreUIViewControllerMappingObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIViewControllerMappingObject.m; sourceTree = ""; }; D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Scroller.swift; sourceTree = ""; }; @@ -496,6 +498,7 @@ D260D7B022D65BDD007E7233 /* MVMCoreUIPageControl.m */, D260D7B522D68509007E7233 /* MVMCoreUIPagingProtocol.h */, D2D6CD3F22E78C1A00D701B8 /* Scroller.swift */, + D2B1E3E422F37D6A0065F95C /* ImageHeadlineBody.swift */, ); path = Molecules; sourceTree = ""; @@ -995,6 +998,7 @@ D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */, D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */, D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */, + D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */, D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */, D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */, D29DF11821E6805F003B2FB9 /* NSLayoutConstraint+MFConvenience.m in Sources */, diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift index 1debda74..c0066afe 100644 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift @@ -215,6 +215,7 @@ import UIKit // MARK: - MVMCoreUIMoleculeViewProtocol functions open override func setAsMolecule() { addSizeConstraintsForAspectRatio = true + pinEdges(.all) } public override static func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { diff --git a/MVMCoreUI/Atoms/Views/MFView.m b/MVMCoreUI/Atoms/Views/MFView.m index 937da3f2..740c5ad5 100644 --- a/MVMCoreUI/Atoms/Views/MFView.m +++ b/MVMCoreUI/Atoms/Views/MFView.m @@ -46,6 +46,10 @@ #pragma mark - MVMCoreUIMoleculeViewProtocol +- (void)setAsMolecule { + self.translatesAutoresizingMaskIntoConstraints = NO; +} + - (void)reset { self.backgroundColor = [UIColor clearColor]; } diff --git a/MVMCoreUI/Atoms/Views/ViewConstrainingView.m b/MVMCoreUI/Atoms/Views/ViewConstrainingView.m index 4b4ad4eb..f46916b3 100644 --- a/MVMCoreUI/Atoms/Views/ViewConstrainingView.m +++ b/MVMCoreUI/Atoms/Views/ViewConstrainingView.m @@ -347,9 +347,6 @@ } } -- (void)setAsMolecule { -} - - (void)setWithJSON:(NSDictionary *)json delegateObject:(MVMCoreUIDelegateObject *)delegateObject additionalData:(NSDictionary *)additionalData { [super setWithJSON:json delegateObject:delegateObject additionalData:additionalData]; diff --git a/MVMCoreUI/Molecules/Carousel.swift b/MVMCoreUI/Molecules/Carousel.swift index db796782..d0efcce3 100644 --- a/MVMCoreUI/Molecules/Carousel.swift +++ b/MVMCoreUI/Molecules/Carousel.swift @@ -255,6 +255,10 @@ extension Carousel: UICollectionViewDelegateFlowLayout { let itemWidth = collectionView.bounds.width * itemWidthPercent return CGSize(width: itemWidth, height: collectionView.bounds.height) } + + public func collectionView(_ collectionView: UICollectionView, didEndDisplaying cell: UICollectionViewCell, forItemAt indexPath: IndexPath) { + (cell as? MoleculeCollectionViewCell)?.setPeaking(false, animated: false) + } } extension Carousel: UICollectionViewDataSource { diff --git a/MVMCoreUI/Molecules/HeadlineBody.swift b/MVMCoreUI/Molecules/HeadlineBody.swift index 9eaa602f..d3c37261 100644 --- a/MVMCoreUI/Molecules/HeadlineBody.swift +++ b/MVMCoreUI/Molecules/HeadlineBody.swift @@ -11,6 +11,7 @@ import UIKit open class HeadlineBody: ViewConstrainingView { let headlineLabel = Label.commonLabelH2(true) let messageLabel = Label.commonLabelB2(true) + var spaceBetweenLabelsConstant = PaddingTwo var spaceBetweenLabels: NSLayoutConstraint? var leftConstraintTitle: NSLayoutConstraint? var rightConstraintTitle: NSLayoutConstraint? @@ -44,7 +45,7 @@ open class HeadlineBody: ViewConstrainingView { topPin = headlineLabel.topAnchor.constraint(equalTo: topAnchor, constant: 0) topPin?.isActive = true - spaceBetweenLabels = messageLabel.topAnchor.constraint(equalTo: headlineLabel.bottomAnchor, constant: PaddingTwo) + spaceBetweenLabels = messageLabel.topAnchor.constraint(equalTo: headlineLabel.bottomAnchor, constant: spaceBetweenLabelsConstant) spaceBetweenLabels?.isActive = true leftConstraintTitle = headlineLabel.leftAnchor.constraint(equalTo: leftAnchor) @@ -66,7 +67,7 @@ open class HeadlineBody: ViewConstrainingView { // MARK: - Constraining public func setSpacing() { if headlineLabel.hasText && messageLabel.hasText { - spaceBetweenLabels?.constant = PaddingTwo + spaceBetweenLabels?.constant = spaceBetweenLabelsConstant } else { spaceBetweenLabels?.constant = 0 } @@ -96,6 +97,7 @@ open class HeadlineBody: ViewConstrainingView { super.reset() headlineLabel.styleH2(true) messageLabel.styleB2(true) + spaceBetweenLabelsConstant = PaddingTwo } public override static func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { diff --git a/MVMCoreUI/Molecules/ImageHeadlineBody.swift b/MVMCoreUI/Molecules/ImageHeadlineBody.swift new file mode 100644 index 00000000..f1e295fe --- /dev/null +++ b/MVMCoreUI/Molecules/ImageHeadlineBody.swift @@ -0,0 +1,85 @@ +// +// ImageHeadlineBody.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 8/1/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers open class ImageHeadlineBody: ViewConstrainingView { + let headlineBody = HeadlineBody(frame: .zero) + let imageView = MFLoadImageView() + var constraintBetweenImageLabelsConstant: CGFloat = 16 + var constraintBetweenImageLabels: NSLayoutConstraint? + + // MARK: - MFViewProtocol + + open override func setupView() { + guard subviews.count == 0 else { + return + } + MVMCoreUIUtility.setMarginsFor(self, leading: 0, top: 0, trailing: 0, bottom: 0) + headlineBody.headlineLabel.styleB1(true) + headlineBody.spaceBetweenLabelsConstant = 0 + addSubview(headlineBody) + addSubview(imageView) + + NSLayoutConstraint.pinViewTop(toSuperview: headlineBody, useMargins: true, constant: 0).isActive = true + NSLayoutConstraint.pinViewRight(toSuperview: headlineBody, useMargins: true, constant: 0).isActive = true + layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: headlineBody.bottomAnchor).isActive = true + var constraint = NSLayoutConstraint.pinViewBottom(toSuperview: headlineBody, useMargins: true, constant: 0) + constraint.priority = .defaultLow + constraint.isActive = true + + imageView.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true + NSLayoutConstraint.pinViewLeft(toSuperview: imageView, useMargins: true, constant: 0).isActive = true + imageView.topAnchor.constraint(greaterThanOrEqualTo: layoutMarginsGuide.topAnchor).isActive = true + layoutMarginsGuide.bottomAnchor.constraint(greaterThanOrEqualTo: imageView.bottomAnchor).isActive = true + constraint = NSLayoutConstraint.pinViewBottom(toSuperview: imageView, useMargins: true, constant: 0) + constraint.priority = UILayoutPriority(rawValue: 200) + constraint.isActive = true + constraint = NSLayoutConstraint.pinViewTop(toSuperview: imageView, useMargins: true, constant: 0) + constraint.priority = UILayoutPriority(rawValue: 200) + constraint.isActive = true + + constraintBetweenImageLabels = headlineBody.leadingAnchor.constraint(equalTo: imageView.trailingAnchor, constant: constraintBetweenImageLabelsConstant) + constraintBetweenImageLabels?.isActive = true + } + + open override func updateView(_ size: CGFloat) { + super.updateView(size) + headlineBody.updateView(size) + imageView.updateView(size) + } + + // MARK: - MVMCoreUIMoleculeViewProtocol + + open override func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) { + super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) + headlineBody.setWithJSON(json?.optionalDictionaryForKey("headlineBody"), delegateObject: delegateObject, additionalData: additionalData) + + let imageJSON = json?.optionalDictionaryForKey("image") + imageView.setWithJSON(imageJSON, delegateObject: delegateObject, additionalData: additionalData) + constraintBetweenImageLabels?.constant = imageJSON != nil ? constraintBetweenImageLabelsConstant : 0 + } + + open override func setAsMolecule() { + super.setAsMolecule() + headlineBody.setAsMolecule() + imageView.setAsMolecule() + } + + open override func reset() { + super.reset() + headlineBody.reset() + headlineBody.headlineLabel.styleB1(true) + headlineBody.spaceBetweenLabelsConstant = 0 + imageView.reset() + } + + public override static func estimatedHeight(forRow json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?) -> CGFloat { + return 95 + } +} diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index c8a0b040..41513bf0 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -53,7 +53,8 @@ @"carousel": Carousel.class, @"carouselItem": MoleculeCollectionViewCell.class, @"barsPager": MVMCoreUIPageControl.class, - @"scroller": Scroller.class + @"scroller": Scroller.class, + @"imageHeadlineBody": ImageHeadlineBody.class } mutableCopy]; }); return mapping;