diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift index 996dea95..1debda74 100644 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift +++ b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift @@ -155,6 +155,39 @@ import UIKit return false } + // MARK: - Constraints + + func setHeight(_ height: CGFloat) { + if let heightConstraint = heightConstraint, MVMCoreGetterUtility.cgfequal(heightConstraint.multiplier, 1) { + heightConstraint.constant = height + } else { + heightConstraint?.isActive = false + heightConstraint = imageView.heightAnchor.constraint(equalToConstant: height) + heightConstraint?.priority = UILayoutPriority(rawValue: 900) + } + heightConstraint?.isActive = true + } + + func setWidth(_ width: CGFloat) { + if let widthConstraint = widthConstraint, MVMCoreGetterUtility.cgfequal(widthConstraint.multiplier, 1) { + widthConstraint.constant = width + } else { + widthConstraint = imageView.widthAnchor.constraint(equalToConstant: width) + widthConstraint?.priority = UILayoutPriority(rawValue: 900) + } + widthConstraint?.isActive = true + } + + func layoutWillChange(width: CGFloat?, height: CGFloat?, size: CGSize?) -> Bool { + guard addSizeConstraintsForAspectRatio else { + return false + } + 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 + } + // Constrains the image view to be the size provided. Used to size it to the image to fix aspect fit defect. func addConstraints(width: NSNumber?, height: NSNumber?, size: CGSize?) { widthConstraint?.isActive = false @@ -164,21 +197,19 @@ import UIKit } if let width = width, let height = height { - heightConstraint = imageView.heightAnchor.constraint(equalToConstant: height.cgfloat()) - widthConstraint = imageView.widthAnchor.constraint(equalToConstant: width.cgfloat()) + setHeight(height.cgfloat()) + setWidth(width.cgfloat()) } else if let width = width, let size = size { - widthConstraint = imageView.widthAnchor.constraint(equalToConstant: width.cgfloat()) + setWidth(width.cgfloat()) heightConstraint = imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: size.height/size.width) + heightConstraint?.priority = UILayoutPriority(rawValue: 900) + heightConstraint?.isActive = true } else if let height = height, let size = size { - heightConstraint = imageView.heightAnchor.constraint(equalToConstant: height.cgfloat()) + setHeight(height.cgfloat()) widthConstraint = imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor, multiplier: size.width/size.height) + widthConstraint?.priority = UILayoutPriority(rawValue: 900) + widthConstraint?.isActive = true } - widthConstraint?.priority = UILayoutPriority(rawValue: 900) - heightConstraint?.priority = UILayoutPriority(rawValue: 900) - heightConstraint?.isActive = true - widthConstraint?.isActive = true - imageView.setContentHuggingPriority(UILayoutPriority.defaultLow, for: NSLayoutConstraint.Axis.horizontal) - imageView.setContentHuggingPriority(UILayoutPriority.defaultLow, for: NSLayoutConstraint.Axis.vertical) } // MARK: - MVMCoreUIMoleculeViewProtocol functions @@ -200,6 +231,13 @@ import UIKit } let width = json?.optionalCGFloatForKey("width") ?? imageWidth let height = json?.optionalCGFloatForKey("height") ?? imageHeight + // For smoother transitions, set constraints that we know immediately. + if let width = width, addSizeConstraintsForAspectRatio { + setWidth(width) + } + if let height = height, addSizeConstraintsForAspectRatio { + setHeight(height) + } if let imageName = json?.optionalStringForKey("image"), shouldLoadImage(withName: imageName, width: width, height: height) { imageView.image = nil imageView.animatedImage = nil @@ -225,8 +263,11 @@ import UIKit 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?.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated?(self!) + if layoutWillChange { + self?.delegateObject?.moleculeDelegate?.moleculeLayoutUpdated?(self!) + } completionHandler(image,data,isFallbackImage) })}