diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift index 2a72481e..c11ffffe 100644 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift @@ -22,6 +22,7 @@ import UIKit var edges: UIRectEdge? var spinnerHeight: CGFloat? var width: CGFloat? + var height: CGFloat? var loadingImageName: String? var isFallbackImage: Bool = false @@ -50,62 +51,24 @@ import UIKit imageView.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: NSLayoutConstraint.Axis.vertical) } - if let topPin = topPin { - removeConstraint(topPin) - } - if edge.contains(UIRectEdge.top) { - topPin = imageView.topAnchor.constraint(equalTo: topAnchor) + if edge.contains(UIRectEdge.top) && edge.contains(UIRectEdge.bottom) { + alignFillVertical() + } else if edge.contains(UIRectEdge.top) { + alignTop() + } else if edge.contains(UIRectEdge.bottom) { + alignBottom() } else { - topPin = imageView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor) + alignCenterVertical() } - topPin?.isActive = true - if let bottomPin = bottomPin { - removeConstraint(bottomPin) - } - if edge.contains(UIRectEdge.bottom) { - bottomPin = bottomAnchor.constraint(equalTo: imageView.bottomAnchor) + if edge.contains(UIRectEdge.left) && edge.contains(UIRectEdge.right) { + alignFillHorizontal() + } else if edge.contains(UIRectEdge.left) { + alignLeft() + } else if edge.contains(UIRectEdge.right) { + alignRight() } else { - bottomPin = bottomAnchor.constraint(greaterThanOrEqualTo: imageView.bottomAnchor) - } - bottomPin?.isActive = true - - if let leftPin = leftPin { - removeConstraint(leftPin) - } - if edge.contains(UIRectEdge.left) { - leftPin = imageView.leftAnchor.constraint(equalTo: leftAnchor) - } else { - leftPin = imageView.leftAnchor.constraint(greaterThanOrEqualTo: leftAnchor) - } - leftPin?.isActive = true - - if let rightPin = rightPin { - removeConstraint(rightPin) - } - if edge.contains(UIRectEdge.right) { - rightPin = rightAnchor.constraint(equalTo: imageView.rightAnchor) - } else { - rightPin = rightAnchor.constraint(greaterThanOrEqualTo: imageView.rightAnchor) - } - rightPin?.isActive = true - - // If neither the top or the bottom are pinned, center it. - if let centerY = centerY { - removeConstraint(centerY) - } - if !edge.contains(UIRectEdge.top) && !edge.contains(UIRectEdge.bottom) { - centerY = imageView.centerYAnchor.constraint(equalTo: centerYAnchor) - centerY?.isActive = true - } - - // If neither the left or the right are pinned, center it. - if let centerX = centerX { - removeConstraint(centerX) - } - if !edge.contains(UIRectEdge.left) && !edge.contains(UIRectEdge.right) { - centerX = imageView.centerXAnchor.constraint(equalTo: centerXAnchor) - centerX?.isActive = true + alignCenterHorizontal() } } @@ -121,6 +84,7 @@ import UIKit // Setup image. imageView.translatesAutoresizingMaskIntoConstraints = false; addSubview(imageView) + pinView(toSuperView: imageView) // Setup edges constraints if edges == nil { @@ -162,7 +126,27 @@ import UIKit guard let currentWidth = self.width else { return true } - return (imageView.image == nil && imageView.animatedImage == nil) || imageName != loadingImageName || !MVMCoreGetterUtility.cgfequal(width, currentWidth) || self.isFallbackImage + return (imageView.image == nil && imageView.animatedImage == nil) || imageName != loadingImageName || !MVMCoreGetterUtility.cgfequal(width, currentWidth) || isFallbackImage + } + + open func shouldLoadImage(withName imageName: String?, width: CGFloat?, height: CGFloat?) -> Bool { + // We should load a new image if there is no current image, the image names are different, or we are using a fallback image. + if ((imageView.image == nil && imageView.animatedImage == nil) || imageName != loadingImageName || isFallbackImage) { + return true + } + // load new image if the width is different + if let oldWidth = self.width, let newWidth = width, !MVMCoreGetterUtility.cgfequal(oldWidth, newWidth) { + return true + } else if (self.width != nil && width == nil) || (self.width == nil && width != nil) { + return true + } + // load new image if the height is different + if let oldHeight = self.height, let newHeight = height, !MVMCoreGetterUtility.cgfequal(oldHeight, newHeight) { + return true + } else if (self.height != nil && height == nil) || (self.height == nil && height != nil) { + return true + } + return false } // Constrains the image view to be the size provided. Used to size it to the image to fix aspect fit defect. @@ -191,17 +175,11 @@ import UIKit imageView.setContentHuggingPriority(UILayoutPriority.defaultLow, for: NSLayoutConstraint.Axis.vertical) } - open override func updateView(_ size: CGFloat) { - super.updateView(size) - let width = size.rounded() - if let imageName = json?.optionalStringForKey("image"), shouldLoadImage(withName: imageName, width: width) { - imageView.image = nil - imageView.animatedImage = nil - loadImage(withName: imageName, format: json?.optionalStringForKey("imageFormat"), width: NSNumber(value: Double(width)), height: nil, customFallbackImage: json?.optionalStringForKey("fallbackImage")) - } + // MARK: - MVMCoreUIMoleculeViewProtocol functions + open override func setAsMolecule() { + addSizeConstraintsForAspectRatio = true } - // MARK: - MVMCoreUIMoleculeViewProtocol functions open override func setWithJSON(_ json: [AnyHashable: Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable: Any]?) { super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData) if let backgroundColorString = json?.optionalStringForKey(KeyBackgroundColor) { @@ -212,6 +190,21 @@ import UIKit imageView.accessibilityTraits = .staticText imageView.isAccessibilityElement = true } + let width = json?.optionalCGFloatForKey("width") + let height = json?.optionalCGFloatForKey("height") + if let imageName = json?.optionalStringForKey("image"), shouldLoadImage(withName: imageName, width: width, height: height) { + imageView.image = nil + imageView.animatedImage = nil + var widthNumber: NSNumber? + if let width = width { + widthNumber = NSNumber(value: Double(width)) + } + var heightNumber: NSNumber? + if let height = height { + heightNumber = NSNumber(value: Double(height)) + } + loadImage(withName: imageName, format: json?.optionalStringForKey("imageFormat"), width: widthNumber, height: heightNumber, customFallbackImage: json?.optionalStringForKey("fallbackImage")) + } } // MARK: - load functions @@ -221,6 +214,9 @@ import UIKit if let width = width { self.width = width.cgfloat() } + if let height = height { + self.height = height.cgfloat() + } self.loadingSpinner.resumeSpinnerAfterDelay() if let height = self.spinnerHeight { self.loadingSpinnerHeightConstraint?.constant = height diff --git a/MVMCoreUI/Molecules/MoleculeStackView.swift b/MVMCoreUI/Molecules/MoleculeStackView.swift index 7c72cf09..d2a70402 100644 --- a/MVMCoreUI/Molecules/MoleculeStackView.swift +++ b/MVMCoreUI/Molecules/MoleculeStackView.swift @@ -163,7 +163,7 @@ public class MoleculeStackView: ViewConstrainingView { alignVertical(ViewConstrainingView.getAlignmentFor(json?.optionalStringForKey("alignment"), defaultAlignment: .fill)) } else { alignHorizontal(ViewConstrainingView.getAlignmentFor(json?.optionalStringForKey("alignment"), defaultAlignment: .fill)) - alignVertical(.leading) + alignVertical(.fill) } // Adds the molecules and sets the json. diff --git a/MVMCoreUI/Molecules/MoleculeTableViewCell.swift b/MVMCoreUI/Molecules/MoleculeTableViewCell.swift index 695b5849..be6f1a71 100644 --- a/MVMCoreUI/Molecules/MoleculeTableViewCell.swift +++ b/MVMCoreUI/Molecules/MoleculeTableViewCell.swift @@ -105,6 +105,11 @@ import UIKit } } else { molecule?.setWithJSON(moleculeJSON, delegateObject: delegateObject, additionalData: additionalData) + if let castView = molecule as? MVMCoreUIViewConstrainingProtocol { + let standardConstraints = castView.useStandardConstraints?() ?? true + castView.shouldSetHorizontalMargins?(!standardConstraints) + castView.shouldSetVerticalMargins?(!standardConstraints) + } } backgroundColor = molecule?.backgroundColor diff --git a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m index 309491bf..07d3e548 100644 --- a/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m +++ b/MVMCoreUI/OtherHandlers/MVMCoreUIMoleculeMappingObject.m @@ -42,7 +42,8 @@ @"checkbox": MVMCoreUICheckBox.class, @"listItem": MoleculeTableViewCell.class, @"switchLineItem": SwitchLineItem.class, - @"switch": Switch.class + @"switch": Switch.class, + @"image": MFLoadImageView.class } mutableCopy]; }); return mapping;