From 33510a648447d8a1ee7dd35ce059f551ad425017 Mon Sep 17 00:00:00 2001 From: "Pfeil, Scott Robert" Date: Tue, 19 Mar 2019 13:11:02 -0400 Subject: [PATCH] Loadimageview to swift --- MVMCoreUI.xcodeproj/project.pbxproj | 24 +- MVMCoreUI/Atoms/Views/MFLoadImageView.h | 76 ----- MVMCoreUI/Atoms/Views/MFLoadImageView.m | 308 ------------------ MVMCoreUI/Atoms/Views/MFLoadImageView.swift | 283 ++++++++++++++++ MVMCoreUI/Atoms/Views/MFTransparentGIFView.h | 33 -- MVMCoreUI/Atoms/Views/MFTransparentGIFView.m | 74 ----- .../MFScrollingViewController.m | 4 +- MVMCoreUI/BaseControllers/MFViewController.m | 2 +- MVMCoreUI/MVMCoreUI.h | 2 - .../TopAlert/MVMCoreUITopAlertMainView.m | 4 +- 10 files changed, 296 insertions(+), 514 deletions(-) delete mode 100644 MVMCoreUI/Atoms/Views/MFLoadImageView.h delete mode 100644 MVMCoreUI/Atoms/Views/MFLoadImageView.m create mode 100644 MVMCoreUI/Atoms/Views/MFLoadImageView.swift delete mode 100644 MVMCoreUI/Atoms/Views/MFTransparentGIFView.h delete mode 100644 MVMCoreUI/Atoms/Views/MFTransparentGIFView.m diff --git a/MVMCoreUI.xcodeproj/project.pbxproj b/MVMCoreUI.xcodeproj/project.pbxproj index a6a4447b..a222046d 100644 --- a/MVMCoreUI.xcodeproj/project.pbxproj +++ b/MVMCoreUI.xcodeproj/project.pbxproj @@ -20,6 +20,8 @@ D22D1F562204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h in Headers */ = {isa = PBXBuildFile; fileRef = D22D1F542204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h */; settings = {ATTRIBUTES = (Public, ); }; }; D22D1F572204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = D22D1F552204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m */; }; D274CA332236A78900B01B62 /* StandardFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D274CA322236A78900B01B62 /* StandardFooterView.swift */; }; + D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */; }; + D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */; }; D28B4F8A21FF967C00712C7A /* MVMCoreUIObject.h in Headers */ = {isa = PBXBuildFile; fileRef = D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */; settings = {ATTRIBUTES = (Public, ); }; }; D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */ = {isa = PBXBuildFile; fileRef = D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */; }; D29770C821F7C4AE00B2F0D0 /* TopLabelsView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */; }; @@ -80,10 +82,6 @@ D29DF25921E6A22D003B2FB9 /* MFButtonProtocol.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF25821E6A22D003B2FB9 /* MFButtonProtocol.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF25C21E6A2B6003B2FB9 /* DashLine.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF25A21E6A2B6003B2FB9 /* DashLine.h */; settings = {ATTRIBUTES = (Public, ); }; }; D29DF25D21E6A2B6003B2FB9 /* DashLine.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF25B21E6A2B6003B2FB9 /* DashLine.m */; }; - D29DF26021E6A985003B2FB9 /* MFLoadImageView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF25E21E6A985003B2FB9 /* MFLoadImageView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D29DF26121E6A985003B2FB9 /* MFLoadImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF25F21E6A985003B2FB9 /* MFLoadImageView.m */; }; - D29DF26421E6A9D9003B2FB9 /* MFTransparentGIFView.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF26221E6A9D9003B2FB9 /* MFTransparentGIFView.h */; settings = {ATTRIBUTES = (Public, ); }; }; - D29DF26521E6A9D9003B2FB9 /* MFTransparentGIFView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF26321E6A9D9003B2FB9 /* MFTransparentGIFView.m */; }; D29DF26C21E6AA0B003B2FB9 /* FLAnimatedImage.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF26821E6AA0B003B2FB9 /* FLAnimatedImage.m */; }; D29DF26D21E6AA0B003B2FB9 /* FLAnimatedImageView.m in Sources */ = {isa = PBXBuildFile; fileRef = D29DF26921E6AA0B003B2FB9 /* FLAnimatedImageView.m */; }; D29DF26E21E6AA0B003B2FB9 /* FLAnimatedImage.h in Headers */ = {isa = PBXBuildFile; fileRef = D29DF26A21E6AA0B003B2FB9 /* FLAnimatedImage.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -176,6 +174,8 @@ D22D1F542204CE5D0077CEC0 /* MVMCoreUIStackableViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIStackableViewController.h; sourceTree = ""; }; D22D1F552204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIStackableViewController.m; sourceTree = ""; }; D274CA322236A78900B01B62 /* StandardFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardFooterView.swift; sourceTree = ""; }; + D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFLoadImageView.swift; sourceTree = ""; }; + D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFTransparentGIFView.swift; sourceTree = ""; }; D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIObject.h; sourceTree = ""; }; D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIObject.m; sourceTree = ""; }; D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsView.m; sourceTree = ""; }; @@ -246,10 +246,6 @@ D29DF25821E6A22D003B2FB9 /* MFButtonProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFButtonProtocol.h; sourceTree = ""; }; D29DF25A21E6A2B6003B2FB9 /* DashLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DashLine.h; sourceTree = ""; }; D29DF25B21E6A2B6003B2FB9 /* DashLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DashLine.m; sourceTree = ""; }; - D29DF25E21E6A985003B2FB9 /* MFLoadImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFLoadImageView.h; sourceTree = ""; }; - D29DF25F21E6A985003B2FB9 /* MFLoadImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFLoadImageView.m; sourceTree = ""; }; - D29DF26221E6A9D9003B2FB9 /* MFTransparentGIFView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFTransparentGIFView.h; sourceTree = ""; }; - D29DF26321E6A9D9003B2FB9 /* MFTransparentGIFView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFTransparentGIFView.m; sourceTree = ""; }; D29DF26821E6AA0B003B2FB9 /* FLAnimatedImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLAnimatedImage.m; sourceTree = ""; }; D29DF26921E6AA0B003B2FB9 /* FLAnimatedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLAnimatedImageView.m; sourceTree = ""; }; D29DF26A21E6AA0B003B2FB9 /* FLAnimatedImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLAnimatedImage.h; sourceTree = ""; }; @@ -556,10 +552,8 @@ D2C5001C21F8EE66001DA659 /* LabelWithInternalButton.m */, D29DF28721E7AC2B003B2FB9 /* ViewConstrainingView.h */, D29DF28821E7AC2B003B2FB9 /* ViewConstrainingView.m */, - D29DF26221E6A9D9003B2FB9 /* MFTransparentGIFView.h */, - D29DF26321E6A9D9003B2FB9 /* MFTransparentGIFView.m */, - D29DF25E21E6A985003B2FB9 /* MFLoadImageView.h */, - D29DF25F21E6A985003B2FB9 /* MFLoadImageView.m */, + D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */, + D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */, D29DF2AD21E7B3A4003B2FB9 /* MFTextView.h */, D29DF2AB21E7B3A4003B2FB9 /* MFTextView.m */, D29DF2AC21E7B3A4003B2FB9 /* MFTextView.xib */, @@ -704,7 +698,6 @@ buildActionMask = 2147483647; files = ( D29DF18021E69E49003B2FB9 /* MFView.h in Headers */, - D29DF26421E6A9D9003B2FB9 /* MFTransparentGIFView.h in Headers */, D29DF27921E7A533003B2FB9 /* MVMCoreUISession.h in Headers */, D29DF25C21E6A2B6003B2FB9 /* DashLine.h in Headers */, D206997721FB8A0B00CAE0DE /* MVMCoreUINavigationController.h in Headers */, @@ -765,7 +758,6 @@ D29DF17421E69E1F003B2FB9 /* MFCustomButton.h in Headers */, D29DF29721E7ADB8003B2FB9 /* MFScrollingViewController.h in Headers */, D29DF26F21E6AA0B003B2FB9 /* FLAnimatedImageView.h in Headers */, - D29DF26021E6A985003B2FB9 /* MFLoadImageView.h in Headers */, D29DF2A121E7AF4E003B2FB9 /* MVMCoreUIUtility.h in Headers */, D29DF17621E69E1F003B2FB9 /* PrimaryButton.h in Headers */, D29DF2C821E7BFC1003B2FB9 /* MFSizeObject.h in Headers */, @@ -860,6 +852,7 @@ D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */, D29DF29621E7ADB8003B2FB9 /* StackableViewController.m in Sources */, D22D1F1F220343560077CEC0 /* MVMCoreUICheckMarkView.m in Sources */, + D282AAB4223FDDAE00C46919 /* MFLoadImageView.swift in Sources */, D29DF11721E6805F003B2FB9 /* UIColor+MFConvenience.m in Sources */, D29DF25321E6A177003B2FB9 /* MFDigitTextField.m in Sources */, D29770F921F7C73800B2F0D0 /* PrimaryButtonView.m in Sources */, @@ -878,7 +871,7 @@ D29DF2A221E7AF4E003B2FB9 /* MVMCoreUIUtility.m in Sources */, D29DF12B21E6851E003B2FB9 /* MVMCoreUITopAlertExpandableView.m in Sources */, D29DF25421E6A177003B2FB9 /* MFMdnTextField.m in Sources */, - D29DF26521E6A9D9003B2FB9 /* MFTransparentGIFView.m in Sources */, + D282AABA224131D100C46919 /* MFTransparentGIFView.swift in Sources */, D2A514672213885800345BFB /* StandardHeaderView.swift in Sources */, D29DF13021E6851E003B2FB9 /* MVMCoreUITopAlertShortView.m in Sources */, D28B4F8B21FF967C00712C7A /* MVMCoreUIObject.m in Sources */, @@ -888,7 +881,6 @@ D29DF18121E69E50003B2FB9 /* MFView.m in Sources */, D29DF18321E69E54003B2FB9 /* SeparatorView.m in Sources */, D29DF17A21E69E1F003B2FB9 /* MFCustomButton.m in Sources */, - D29DF26121E6A985003B2FB9 /* MFLoadImageView.m in Sources */, D274CA332236A78900B01B62 /* StandardFooterView.swift in Sources */, D29DF2BF21E7BEA4003B2FB9 /* MVMCoreUITabBarPageControlViewController.m in Sources */, D29DF28321E7AB24003B2FB9 /* MVMCoreUICommonViewsUtility.m in Sources */, diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.h b/MVMCoreUI/Atoms/Views/MFLoadImageView.h deleted file mode 100644 index 895da071..00000000 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.h +++ /dev/null @@ -1,76 +0,0 @@ -// -// MFLoadImageView.h -// mobilefirst -// -// Created by Scott Pfeil on 5/26/16. -// Copyright © 2016 Verizon Wireless. All rights reserved. -// -// Shows a loading indicator while the image is downloading and then replaces loading indicator with image after - -#import -#import -@import MVMCore.MVMCoreCache; - -@class MFLoadingSpinner; - -@interface MFLoadImageView : UIView - -@property (nonnull, strong, nonatomic) MFLoadingSpinner *loadingSpinner; -@property (nonnull, strong, nonatomic) MFTransparentGIFView *imageView; - -@property (nullable, weak, nonatomic) NSLayoutConstraint *leftPin; -@property (nullable, weak, nonatomic) NSLayoutConstraint *rightPin; -@property (nullable, weak, nonatomic) NSLayoutConstraint *topPin; -@property (nullable, weak, nonatomic) NSLayoutConstraint *centerX; -@property (nullable, weak, nonatomic) NSLayoutConstraint *centerY; -@property (nullable, weak, nonatomic) NSLayoutConstraint *bottomPin; - -@property (nullable, weak, nonatomic) NSLayoutConstraint *widthConstraint; -@property (nullable, weak, nonatomic) NSLayoutConstraint *heightConstraint; - -// If true, will add size constraints once the image is downloaded. This will help remove white space for aspect fit issues. -@property (nonatomic) BOOL addSizeConstraintsForAspectRatio; - -// image loaded in the center. -- (nonnull instancetype)initWithCenteredImage; - -// Use to pin edges for the image. Shouldn't pin both left and right or top and bottom because then the image will stretch. -- (nonnull instancetype)initWithPinnedEdges:(UIRectEdge)edge; - -// Returns the default setter block to be used -- (nonnull MVMCoreGetImageBlock)defaultCompletionBlock; - -// Allows to pin edges after initialization -- (void)pinEdges:(UIRectEdge)edge; - -// Helper for if we need to load a new image. Returns true if: there is no current image, imageName and the current loadingImageName are not the same, width and the current width are not the same, we are using a fallback image. -- (BOOL)shouldLoadImageWithName:(nullable NSString *)imageName width:(CGFloat)width; - -// Loads an image with the name. This function will use the scene 7 MFCache function to download from server or from local -// @param imageName The string for the image, url or local name -// @param format The scene 7 format of the image -// @param width The scene7 width. -// @param height The scene7 height. -// @param customFallbackImage if nil, the default fallback for MF is used. -// @param completionHandler can be used to define a custom completion handler. Useful when loading images in a collection view. Load a UIImage when receiving image, load a gif when receiving imageData. -// See MFCache for more information of load image function -- (void)loadImageWithName:(nullable NSString *)imageName; -- (void)loadImageWithName:(nullable NSString *)imageName width:(nullable NSNumber *)width; -- (void)loadImageWithName:(nullable NSString *)imageName height:(nullable NSNumber *)height; -- (void)loadImageWithName:(nullable NSString *)imageName width:(nullable NSNumber *)width height:(nullable NSNumber *)height; -- (void)loadImageWithName:(nullable NSString *)imageName format:(nullable NSString *)format width:(nullable NSNumber *)width height:(nullable NSNumber *)height; -- (void)loadImageWithName:(nullable NSString *)imageName width:(nullable NSNumber *)width height:(nullable NSNumber *)height customFallbackImage:(nullable NSString *)customFallbackImage; -- (void)loadImageWithName:(nullable NSString *)imageName width:(nullable NSNumber *)width height:(nullable NSNumber *)height completionHandler:(nonnull MVMCoreGetImageBlock)completionHandler; -- (void)loadImageWithName:(nullable NSString *)imageName format:(nullable NSString *)format width:(nullable NSNumber *)width height:(nullable NSNumber *)height customFallbackImage:(nullable NSString *)customFallbackImage completionHandler:(nonnull MVMCoreGetImageBlock)completionHandler; -- (void)loadImageWithName:(nullable NSString *)imageName exceptImageType:(nullable NSString *)format width:(nullable NSNumber *)width height:(nullable NSNumber *)height customFallbackImage:(nullable NSString *)customFallbackImage; - -// Loads a cropped image with the name. This function will use the scene 7 MFCache function to download from server or from local -// @param imageName The string for the image, url or local name -// @param width The scene7 width. -// @param height The scene7 height. -// @param cropRect The crop rectangle requested -// @param customFallbackImage if nil, the default fallback for MF is used. -// See MFCache for more information of load image function -- (void)loadCroppedImageWithName:(nullable NSString *)imageName width:(nullable NSNumber *)width height:(nullable NSNumber *)height cropRect:(CGRect)cropRect flipImage:(BOOL)flipImage customFallbackImage:(nullable NSString *)customFallbackImage; - -@end diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.m b/MVMCoreUI/Atoms/Views/MFLoadImageView.m deleted file mode 100644 index 2a0572da..00000000 --- a/MVMCoreUI/Atoms/Views/MFLoadImageView.m +++ /dev/null @@ -1,308 +0,0 @@ -// -// MFLoadImageView.m -// mobilefirst -// -// Created by Scott Pfeil on 5/26/16. -// Copyright © 2016 Verizon Wireless. All rights reserved. -// - -#import "MFLoadImageView.h" -#import "MFLoadingSpinner.h" -#import "NSLayoutConstraint+MFConvenience.h" -#import "MVMCoreUIUtility.h" -@import MVMCore.NSDictionary_MFConvenience; -@import MVMCore.MVMCoreDispatchUtility; -@import MVMCore.MVMCoreGetterUtility; -@import MVMCore.MVMCoreCache; - -@interface MFLoadImageView () - -@property (nonnull, strong, nonatomic) NSLayoutConstraint *loadingSpinnerHeight; -@property (nonatomic) CGFloat height; -@property (strong, nonatomic) NSString *loadingImageName; -@property (nonatomic) CGFloat width; -@property (nonatomic) BOOL isFallbackImage; - -@end - -@implementation MFLoadImageView - -- (instancetype)initWithCoder:(NSCoder *)aDecoder { - if (self = [super initWithCoder:aDecoder]) { - [self setupView:UIRectEdgeNone]; - } - return self; -} - -- (nonnull instancetype)initWithCenteredImage { - return [self initWithPinnedEdges:UIRectEdgeNone]; -} - -- (nonnull instancetype)initWithPinnedEdges:(UIRectEdge)edge { - if (self = [super init]) { - [self setupView:edge]; - } - return self; -} - -- (void)setupView:(UIRectEdge)edge { - - if (!self.imageView) { - self.clipsToBounds = YES; - self.translatesAutoresizingMaskIntoConstraints = NO; - [self setContentHuggingPriority:950 forAxis:UILayoutConstraintAxisHorizontal]; - [self setContentHuggingPriority:950 forAxis:UILayoutConstraintAxisVertical]; - - MFTransparentGIFView *imageView = [[MFTransparentGIFView alloc] initWithFrame:CGRectZero]; - imageView.translatesAutoresizingMaskIntoConstraints = NO; - [self addSubview:imageView]; - self.imageView = imageView; - if (edge == UIRectEdgeAll) { - [imageView setContentHuggingPriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal]; - [imageView setContentHuggingPriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisVertical]; - } else { - [imageView setContentHuggingPriority:900 forAxis:UILayoutConstraintAxisHorizontal]; - [imageView setContentHuggingPriority:900 forAxis:UILayoutConstraintAxisVertical]; - } - - [self pinEdges:edge]; - - MFLoadingSpinner *loadingSpinner = [[MFLoadingSpinner alloc] initWithFrame:CGRectZero]; - loadingSpinner.clipsToBounds = YES; - loadingSpinner.translatesAutoresizingMaskIntoConstraints = NO; - [self addSubview:loadingSpinner]; - self.loadingSpinner = loadingSpinner; - [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|-0@500-[loadingSpinner]-0@500-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(loadingSpinner)]]; - [NSLayoutConstraint activateConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|-0@500-[loadingSpinner]-0@500-|" options:NSLayoutFormatDirectionLeadingToTrailing metrics:nil views:NSDictionaryOfVariableBindings(loadingSpinner)]]; - [NSLayoutConstraint constraintWithItem:loadingSpinner attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0].active = YES; - [NSLayoutConstraint constraintWithItem:loadingSpinner attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0].active = YES; - - self.loadingSpinnerHeight = [[loadingSpinner pinWidthAndHeight] objectForKey:ConstraintHeight ofType:[NSLayoutConstraint class]]; - self.height = self.loadingSpinnerHeight.constant; - self.loadingSpinnerHeight.constant = 0; - self.loadingSpinnerHeight.active = YES; - [loadingSpinner pauseSpinner]; - } -} - -- (void)pinEdges:(UIRectEdge)edge { - - if (self.topPin) { - [self removeConstraint:self.topPin]; - } - NSLayoutRelation relation; - if (edge & UIRectEdgeTop) { - relation = NSLayoutRelationEqual; - } else { - relation = NSLayoutRelationGreaterThanOrEqual; - } - NSLayoutConstraint *constraint = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeTop relatedBy:relation toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0]; - constraint.active = YES; - self.topPin = constraint; - - if (self.bottomPin) { - [self removeConstraint:self.bottomPin]; - } - if (edge & UIRectEdgeBottom) { - relation = NSLayoutRelationEqual; - } else { - relation = NSLayoutRelationGreaterThanOrEqual; - } - constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeBottom relatedBy:relation toItem:self.imageView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0]; - constraint.active = YES; - self.bottomPin = constraint; - - if (self.leftPin) { - [self removeConstraint:self.leftPin]; - } - if (edge & UIRectEdgeLeft) { - relation = NSLayoutRelationEqual; - } else { - relation = NSLayoutRelationGreaterThanOrEqual; - } - constraint = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeLeft relatedBy:relation toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0]; - constraint.active = YES; - self.leftPin = constraint; - - if (self.rightPin) { - [self removeConstraint:self.rightPin]; - } - if (edge & UIRectEdgeRight) { - relation = NSLayoutRelationEqual; - } else { - relation = NSLayoutRelationGreaterThanOrEqual; - } - constraint = [NSLayoutConstraint constraintWithItem:self attribute:NSLayoutAttributeRight relatedBy:relation toItem:self.imageView attribute:NSLayoutAttributeRight multiplier:1.0 constant:0]; - constraint.active = YES; - self.rightPin = constraint; - - if (self.centerY) { - [self removeConstraint:self.centerY]; - } - if ((edge & (UIRectEdgeTop | UIRectEdgeBottom)) == 0) { - constraint = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeCenterY relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterY multiplier:1.0 constant:0]; - constraint.active = YES; - self.centerY = constraint; - } - - if (self.centerX) { - [self removeConstraint:self.centerX]; - } - if ((edge & (UIRectEdgeLeft | UIRectEdgeRight)) == 0) { - constraint = [NSLayoutConstraint constraintWithItem:self.imageView attribute:NSLayoutAttributeCenterX relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeCenterX multiplier:1.0 constant:0]; - constraint.active = YES; - self.centerX = constraint; - } -} - -- (nonnull MVMCoreGetImageBlock)defaultCompletionBlock { - return ^(UIImage * _Nullable image, NSData * _Nullable gifData, BOOL isFallBackImage) { - [MVMCoreDispatchUtility performBlockOnMainThread:^{ - if (image && [image isKindOfClass:[UIImage class]]) { - [self.imageView setImage:image]; - [self layoutIfNeeded]; - } else if (gifData) { - [self.imageView loadGifWithData:gifData]; - [self layoutIfNeeded]; - } - }]; - }; -} - -- (BOOL)shouldLoadImageWithName:(nullable NSString *)imageName width:(CGFloat)width { - return (!self.imageView.image && !self.imageView.animatedImage) || ![imageName isEqualToString:self.loadingImageName] || !fequal(width,self.width) || self.isFallbackImage; -} - -- (void)loadImageWithName:(nullable NSString *)imageName { - [self loadImageWithName:imageName format:nil width:nil height:nil customFallbackImage:nil completionHandler:[self defaultCompletionBlock]]; -} - -- (void)loadImageWithName:(nullable NSString *)imageName width:(nullable NSNumber *)width { - [self loadImageWithName:imageName format:nil width:width height:nil customFallbackImage:nil completionHandler:[self defaultCompletionBlock]]; -} - -- (void)loadImageWithName:(nullable NSString *)imageName height:(nullable NSNumber *)height { - [self loadImageWithName:imageName format:nil width:nil height:height customFallbackImage:nil completionHandler:[self defaultCompletionBlock]]; -} - -- (void)loadImageWithName:(nullable NSString *)imageName width:(nullable NSNumber *)width height:(nullable NSNumber *)height { - [self loadImageWithName:imageName format:nil width:width height:height customFallbackImage:nil completionHandler:[self defaultCompletionBlock]]; -} - -- (void)loadImageWithName:(nullable NSString *)imageName format:(nullable NSString *)format width:(nullable NSNumber *)width height:(nullable NSNumber *)height { - [self loadImageWithName:imageName format:format width:width height:height customFallbackImage:nil completionHandler:[self defaultCompletionBlock]]; -} - -- (void)loadImageWithName:(nullable NSString *)imageName width:(nullable NSNumber *)width height:(nullable NSNumber *)height customFallbackImage:(nullable NSString *)customFallbackImage { - [self loadImageWithName:imageName format:nil width:width height:height customFallbackImage:customFallbackImage completionHandler:[self defaultCompletionBlock]]; -} - -- (void)loadImageWithName:(nullable NSString *)imageName width:(nullable NSNumber *)width height:(nullable NSNumber *)height completionHandler:(nonnull MVMCoreGetImageBlock)completionHandler { - [self loadImageWithName:imageName format:nil width:width height:height customFallbackImage:nil completionHandler:completionHandler]; -} - -- (void)loadImageWithName:(nullable NSString *)imageName exceptImageType:(nullable NSString *)format width:(nullable NSNumber *)width height:(nullable NSNumber *)height customFallbackImage:(nullable NSString *)customFallbackImage { - [self loadImageWithName:imageName format:format width:width height:height customFallbackImage:customFallbackImage completionHandler:[self defaultCompletionBlock]]; -} - -- (void)addConstraintsForWidth:(nullable NSNumber *)width height:(nullable NSNumber *)height size:(CGSize)size { - self.widthConstraint.active = NO; - self.heightConstraint.active = NO; - if (self.addSizeConstraintsForAspectRatio) { - if (width && height) { - NSLayoutConstraint *constraint = [self.imageView.heightAnchor constraintEqualToConstant:height.floatValue]; - constraint.active = YES; - self.heightConstraint = constraint; - constraint = [self.imageView.widthAnchor constraintEqualToConstant:width.floatValue]; - constraint.active = YES; - self.widthConstraint = constraint; - } else if (width) { - NSLayoutConstraint *constraint = [self.imageView.widthAnchor constraintEqualToConstant:width.floatValue]; - constraint.active = YES; - self.widthConstraint = constraint; - constraint = [self.imageView.heightAnchor constraintEqualToAnchor:self.imageView.widthAnchor multiplier:size.height/size.width]; - constraint.active = YES; - self.heightConstraint = constraint; - } else if (height) { - NSLayoutConstraint *constraint = [self.imageView.heightAnchor constraintEqualToConstant:height.floatValue]; - constraint.active = YES; - self.heightConstraint = constraint; - constraint = [self.imageView.widthAnchor constraintEqualToAnchor:self.imageView.heightAnchor multiplier:size.width/size.height]; - constraint.active = YES; - self.widthConstraint = constraint; - } - self.widthConstraint.priority = 900; - self.heightConstraint.priority = 900; - [self.imageView setContentHuggingPriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisHorizontal]; - [self.imageView setContentHuggingPriority:UILayoutPriorityDefaultLow forAxis:UILayoutConstraintAxisVertical]; - } -} - -- (void)loadImageWithName:(nullable NSString *)imageName format:(nullable NSString *)format width:(nullable NSNumber *)width height:(nullable NSNumber *)height customFallbackImage:(nullable NSString *)customFallbackImage completionHandler:(nonnull MVMCoreGetImageBlock)completionHandler { - __weak typeof(self) weakSelf = self; - [MVMCoreDispatchUtility performBlockOnMainThread:^{ - self.loadingImageName = imageName; - self.width = [width floatValue]; - - [self.loadingSpinner resumeSpinnerAfterDelay]; - self.loadingSpinnerHeight.constant = self.height; - - void (^finishedLoadBlock)(UIImage * _Nullable, NSData * _Nullable, BOOL) = ^(UIImage * _Nullable image, NSData * _Nullable imageData, BOOL isFallBackImage) { - [MVMCoreDispatchUtility performBlockOnMainThread:^{ - // Makes sure the last requested image is the one we are loading. - if ([weakSelf.loadingImageName isEqualToString:imageName]) { - weakSelf.isFallbackImage = isFallBackImage; - weakSelf.loadingSpinnerHeight.constant = 0; - [weakSelf.loadingSpinner pauseSpinner]; - [weakSelf addConstraintsForWidth:width height:height size:image.size]; - completionHandler(image, imageData, isFallBackImage); - } - }]; - }; - - NSString *fallBackImageName = [MVMCoreUIUtility localizedImageName:@"fallback"]; - if ([[format lowercaseString] containsString:@"gif"]) { - - // Gifs aren't supported by default and need special handling - [[MVMCoreCache sharedCache] getGif:imageName useWidth:(width ? YES : NO) widthForS7:[width floatValue] useHeight:(height ? YES : NO) heightForS7:[height floatValue] format:format localFallbackImageName:(customFallbackImage ?: fallBackImageName) completionHandler:^(UIImage * _Nullable image, NSData * _Nullable imageData, BOOL isFallBackImage) { - finishedLoadBlock(image, imageData, isFallBackImage); - }]; - } else { - [[MVMCoreCache sharedCache] getImage:imageName useWidth:(width ? YES : NO) widthForS7:[width floatValue] useHeight:(height ? YES : NO) heightForS7:[height floatValue] format:format localFallbackImageName:(customFallbackImage ?: fallBackImageName) completionHandler:^(UIImage * _Nullable image, NSData * _Nullable imageData, BOOL isFallBackImage) { - finishedLoadBlock(image, nil, isFallBackImage); - }]; - } - }]; -} - -- (void)loadCroppedImageWithName:(nullable NSString *)imageName width:(nullable NSNumber *)width height:(nullable NSNumber *)height cropRect:(CGRect)cropRect flipImage:(BOOL)flipImage customFallbackImage:(nullable NSString *)customFallbackImage { - [MVMCoreDispatchUtility performBlockOnMainThread:^{ - self.loadingImageName = imageName; - [self.loadingSpinner resumeSpinnerAfterDelay]; - self.loadingSpinnerHeight.constant = self.height; - - __weak typeof(self) weakSelf = self; - [[MVMCoreCache sharedCache] getCroppedImage:imageName useWidth:(width ? YES : NO) widthForS7:[width floatValue] useHeight:(height ? YES : NO) heightForS7:[height floatValue] finalRect:cropRect flipImage:flipImage localFallbackImageName:(customFallbackImage ?: @"fallback") completionHandler:^(UIImage * _Nullable image, NSData * _Nullable imageData, BOOL isFallBackImage) { - [MVMCoreDispatchUtility performBlockOnMainThread:^{ - if (image && [image isKindOfClass:[UIImage class]] && ([weakSelf.loadingImageName isEqualToString:imageName])) { - weakSelf.loadingSpinnerHeight.constant = 0; - [weakSelf.loadingSpinner pauseSpinner]; - if (flipImage) { - [weakSelf.imageView setImage:[UIImage imageWithCGImage:image.CGImage - scale:image.scale - orientation:UIImageOrientationUpMirrored]]; - } else { - [weakSelf.imageView setImage:image]; - } - } - [weakSelf layoutIfNeeded]; - }]; - }]; - }]; -} - -- (void)setFrame:(CGRect)frame { - [super setFrame:frame]; -} - -@end diff --git a/MVMCoreUI/Atoms/Views/MFLoadImageView.swift b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift new file mode 100644 index 00000000..46a21f78 --- /dev/null +++ b/MVMCoreUI/Atoms/Views/MFLoadImageView.swift @@ -0,0 +1,283 @@ +// +// LoadImageView.swift +// MVMCoreUI +// +// Created by Scott Pfeil on 3/18/19. +// Copyright © 2019 Verizon Wireless. All rights reserved. +// + +import UIKit + +@objcMembers public class MFLoadImageView: ViewConstrainingView { + @objc public let loadingSpinner = MFLoadingSpinner(frame: .zero) + @objc public let imageView = MFTransparentGIFView(frame: .zero) + @objc public var addSizeConstraintsForAspectRatio = false + var centerX: NSLayoutConstraint? + var centerY: NSLayoutConstraint? + var widthConstraint: NSLayoutConstraint? + var heightConstraint: NSLayoutConstraint? + var loadingSpinnerHeightConstraint: NSLayoutConstraint? + + // For keeping track of current state. + private var edges: UIRectEdge? + private var spinnerHeight: CGFloat? + private var width: CGFloat? + private var loadingImageName: String? + private var isFallbackImage: Bool = false + + public init(pinnedEdges edge: UIRectEdge) { + edges = edge + super.init(frame: .zero) + } + + @objc public init() { + edges = UIRectEdge(rawValue: 0) + super.init(frame: .zero) + } + + required init?(coder aDecoder: NSCoder) { + super.init(coder: aDecoder) + } + + @objc public func pinEdges(_ edge: UIRectEdge) { + edges = edge + if edge == UIRectEdge.all { + imageView.setContentHuggingPriority(UILayoutPriority.defaultLow, for: NSLayoutConstraint.Axis.horizontal) + imageView.setContentHuggingPriority(UILayoutPriority.defaultLow, for: NSLayoutConstraint.Axis.vertical) + } else { + imageView.setContentHuggingPriority(UILayoutPriority(rawValue: 900), for: NSLayoutConstraint.Axis.horizontal) + 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) + } else { + topPin = imageView.topAnchor.constraint(greaterThanOrEqualTo: topAnchor) + } + topPin?.isActive = true + + if let bottomPin = bottomPin { + removeConstraint(bottomPin) + } + if edge.contains(UIRectEdge.bottom) { + bottomPin = bottomAnchor.constraint(equalTo: imageView.bottomAnchor) + } 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 + } + } + + override public func setupView() { + super.setupView() + guard subviews.count == 0 else { + return + } + clipsToBounds = true + setContentHuggingPriority(UILayoutPriority(rawValue: 950), for: NSLayoutConstraint.Axis.horizontal) + setContentHuggingPriority(UILayoutPriority(rawValue: 950), for: NSLayoutConstraint.Axis.vertical) + + // Setup image. + imageView.translatesAutoresizingMaskIntoConstraints = false; + addSubview(imageView) + + // Setup edges constraints + if edges == nil { + edges = UIRectEdge(rawValue: 0) + } + pinEdges(edges!) + + // Setup spinner. + loadingSpinner.clipsToBounds = true + loadingSpinner.translatesAutoresizingMaskIntoConstraints = false + addSubview(loadingSpinner) + NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "H:|-0@500-[loadingSpinner]-0@500-|", metrics: nil, views: ["loadingSpinner" : loadingSpinner])) + NSLayoutConstraint.activate(NSLayoutConstraint.constraints(withVisualFormat: "V:|-0@500-[loadingSpinner]-0@500-|", metrics: nil, views: ["loadingSpinner" : loadingSpinner])) + loadingSpinner.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true + loadingSpinner.centerYAnchor.constraint(equalTo: centerYAnchor).isActive = true + if let constraint = loadingSpinner.pinWidthAndHeight()?[ConstraintHeight] as! NSLayoutConstraint? { + loadingSpinnerHeightConstraint = constraint + spinnerHeight = constraint.constant + loadingSpinnerHeightConstraint?.constant = 0 + loadingSpinnerHeightConstraint?.isActive = true + loadingSpinner.pause() + } + } + + @objc public func defaultCompletionBlock() -> MVMCoreGetImageBlock { + return {image,gifData,_ in MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in + if let image = image { + self?.imageView.image = image + self?.layoutIfNeeded() + } else if let gifData = gifData { + self?.imageView.loadGifWithData(gifData) + self?.layoutIfNeeded() + } + })} + } + + @objc public func shouldLoadImageWithName(_ imageName: String?, width: CGFloat) -> Bool { + // We should load a new image if there is no current image, the image names are different, the width is different, or we are using a fallback image. + guard let currentWidth = self.width else { + return true + } + return (imageView.image == nil && imageView.animatedImage == nil) || imageName != loadingImageName || !MVMCoreGetterUtility.cgfequal(width, currentWidth) || self.isFallbackImage + } + + // 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 + heightConstraint?.isActive = false + guard addSizeConstraintsForAspectRatio else { + return + } + + if let width = width, let height = height { + heightConstraint = imageView.heightAnchor.constraint(equalToConstant: height.cgfloat()) + widthConstraint = imageView.widthAnchor.constraint(equalToConstant: width.cgfloat()) + } else if let width = width, let size = size { + widthConstraint = imageView.widthAnchor.constraint(equalToConstant: width.cgfloat()) + heightConstraint = imageView.heightAnchor.constraint(equalTo: imageView.widthAnchor, multiplier: size.height/size.width) + } else if let height = height, let size = size { + heightConstraint = imageView.heightAnchor.constraint(equalToConstant: height.cgfloat()) + widthConstraint = imageView.widthAnchor.constraint(equalTo: imageView.heightAnchor, multiplier: size.width/size.height) + } + 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: - load functions + @objc public func loadImage(withName imageName: String?, format: String?, width: NSNumber?, height: NSNumber?, customFallbackImage: String?, completionHandler: @escaping MVMCoreGetImageBlock) { + MVMCoreDispatchUtility.performBlock(onMainThread: { [unowned self] in + self.loadingImageName = imageName + if let width = width { + self.width = width.cgfloat() + } + self.loadingSpinner.resumeSpinnerAfterDelay() + if let height = self.spinnerHeight { + self.loadingSpinnerHeightConstraint?.constant = height + } + + let finishedLoadingBlock: MVMCoreGetImageBlock = {[weak self] (image, data, isFallbackImage) in MVMCoreDispatchUtility.performBlock(onMainThread: { [weak self] in + guard let loadingImageName = self?.loadingImageName, loadingImageName == imageName else { + return + } + self?.isFallbackImage = isFallbackImage + self?.loadingSpinnerHeightConstraint?.constant = 0 + self?.loadingSpinner.pause() + self?.addConstraints(width: width, height: height, size: image?.size) + completionHandler(image,data,isFallbackImage) + })} + + let fallbackImageName = customFallbackImage ?? MVMCoreUIUtility.localizedImageName("fallback") + if let format = format, format.lowercased().contains("gif") { + // Gifs aren't supported by default and need special handling + MVMCoreCache.shared()?.getGif(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, format: format, localFallbackImageName: fallbackImageName, completionHandler: finishedLoadingBlock) + } else { + MVMCoreCache.shared()?.getImage(imageName, useWidth: width != nil, widthForS7: width?.intValue ?? 0, useHeight: height != nil, heightForS7: height?.intValue ?? 0, localFallbackImageName: fallbackImageName, completionHandler: finishedLoadingBlock) + } + }) + } + + @objc public func loadCroppedImage(withName imageName: + String?, width: NSNumber?, height: NSNumber?, cropRect: CGRect, flipImage: Bool, customFallbackImage: String?) { + MVMCoreDispatchUtility.performBlock(onMainThread: { [unowned self] in + self.loadingImageName = imageName + self.loadingSpinner.resumeSpinnerAfterDelay() + if let height = self.spinnerHeight { + self.loadingSpinnerHeightConstraint?.constant = height + } + 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?.loadingImageName, loadingImageName == imageName else { + return + } + self?.loadingSpinnerHeightConstraint?.constant = 0 + self?.loadingSpinner.pause() + if flipImage, let cgImage = image.cgImage { + self?.imageView.image = UIImage(cgImage: cgImage, scale: image.scale, orientation: UIImage.Orientation.upMirrored) + } else { + self?.imageView.image = image + } + self?.layoutIfNeeded() + }) + }) + }) + } + + @objc public func loadImage(withName imageName: String?) { + loadImage(withName: imageName, format: nil, width: nil, height: nil, customFallbackImage: nil, completionHandler: defaultCompletionBlock()) + } + + @objc public func loadImage(withName imageName: String?, width: NSNumber?) { + loadImage(withName: imageName, format: nil, width: width, height: nil, customFallbackImage: nil, completionHandler: defaultCompletionBlock()) + } + + @objc public func loadImage(withName imageName: String?, height: NSNumber?) { + loadImage(withName: imageName, format: nil, width: nil, height: height, customFallbackImage: nil, completionHandler: defaultCompletionBlock()) + } + + @objc public func loadImage(withName imageName: String?, width: NSNumber?, height: NSNumber?) { + loadImage(withName: imageName, format: nil, width: width, height: height, customFallbackImage: nil, completionHandler: defaultCompletionBlock()) + } + + @objc public func loadImage(withName imageName: String?, format: String?, width: NSNumber?, height: NSNumber?) { + loadImage(withName: imageName, format: format, width: width, height: height, customFallbackImage: nil, completionHandler: defaultCompletionBlock()) + } + + @objc public func loadImage(withName imageName: String?, width: NSNumber?, height: NSNumber?, customFallbackImage: String?) { + loadImage(withName: imageName, format: nil, width: width, height: height, customFallbackImage: customFallbackImage, completionHandler: defaultCompletionBlock()) + } + + @objc public func loadImage(withName imageName: String?, width: NSNumber?, height: NSNumber?, completionHandler: @escaping MVMCoreGetImageBlock) { + loadImage(withName: imageName, format: nil, width: width, height: height, customFallbackImage: nil, completionHandler: completionHandler) + } + + @objc public func loadImage(withName imageName: String?, format: String?, width: NSNumber?, height: NSNumber?, customFallbackImage: String?) { + loadImage(withName: imageName, format: format, width: width, height: height, customFallbackImage: customFallbackImage, completionHandler: defaultCompletionBlock()) + } +} diff --git a/MVMCoreUI/Atoms/Views/MFTransparentGIFView.h b/MVMCoreUI/Atoms/Views/MFTransparentGIFView.h deleted file mode 100644 index 38037395..00000000 --- a/MVMCoreUI/Atoms/Views/MFTransparentGIFView.h +++ /dev/null @@ -1,33 +0,0 @@ -// -// MFTransparentGIFView.h -// mobilefirst -// -// Created by Wesolowski, Brendan on 3/16/16. -// Copyright © 2016 Verizon Wireless. All rights reserved. -// - -#import - -#import - -@interface MFTransparentGIFView : FLAnimatedImageView - -/** Creates the GIF display view with the passed in frame. - frame: frame to set the view to. - ImageName: name of the .gif to load. Should not contain the extension. - StartImmediately: should the gif immeidately begin playing. If YES, it will start. If NO, call [performAnimations] to start it. - Duration: how long the animation takes to loop. Pass a negative value to use the default. - LoopCompletionBlock: a block called whenever the gif finishes a loop. - animatedImage : set as nil when use this view in reusable cell - */ --(nullable instancetype)initWithFrame:(CGRect)frame ImageName:(nonnull NSString *)imageName StartImmediately:(BOOL)startImmediately Duration:(NSTimeInterval)duration LoopCompletionBlock:(void (^ __nullable)(NSUInteger loopCountRemaining))loopCompletionBlock; - --(void)loadImage:(nonnull NSString *)imageName StartImmediately:(BOOL)startImmediately Duration:(NSTimeInterval)duration LoopCompletionBlock:(void (^ __nullable)(NSUInteger))loopCompletionBlock; - --(void)loadGifWithData:(nonnull NSData *)imageData; - --(void)setImageData:(nonnull NSData *)imageData; - --(void)performAnimations; - -@end diff --git a/MVMCoreUI/Atoms/Views/MFTransparentGIFView.m b/MVMCoreUI/Atoms/Views/MFTransparentGIFView.m deleted file mode 100644 index 8c05e1f1..00000000 --- a/MVMCoreUI/Atoms/Views/MFTransparentGIFView.m +++ /dev/null @@ -1,74 +0,0 @@ -// -// MFTransparentGIFView.m -// mobilefirst -// -// Created by Wesolowski, Brendan on 3/16/16. -// Copyright © 2016 Verizon Wireless. All rights reserved. -// - -#import "MFTransparentGIFView.h" -#import "FLAnimatedImage.h" -#import "MVMCoreUIUtility.h" -@import MVMCore.MFFreebeeHandler; -@import MVMCore.MVMCoreConstants; - -@interface MFTransparentGIFView () - -@property (strong, nullable, nonatomic) NSData *imageData; - -@end - -@implementation MFTransparentGIFView - - - --(instancetype)initWithFrame:(CGRect)frame ImageName:(NSString *)imageName StartImmediately:(BOOL)startImmediately Duration:(NSTimeInterval)duration LoopCompletionBlock:(void (^)(NSUInteger))loopCompletionBlock { - if(self = [super initWithFrame:frame]) { - [self loadImage:imageName StartImmediately:startImmediately Duration:duration LoopCompletionBlock:loopCompletionBlock]; - } - return self; -} - --(void)loadImage:(NSString *)imageName StartImmediately:(BOOL)startImmediately Duration:(NSTimeInterval)duration LoopCompletionBlock:(void (^)(NSUInteger))loopCompletionBlock { - self.contentMode = UIViewContentModeScaleAspectFill; - self.clipsToBounds = YES; - - if(duration >= 0.0) { - self.animationDuration = duration; - } - self.loopCompletionBlock = loopCompletionBlock; - self.backgroundColor = [UIColor clearColor]; - - NSURL *url; - if([imageName containsString:@"http"]) { - url = [[NSURL alloc] initWithString:imageName]; - } else { - url = [[MVMCoreUIUtility bundleForMVMCoreUI] URLForResource:imageName withExtension:@"gif"]; - } - self.imageData = [[MFFreebeeHandler sharedHandler] freebee_dataWithContentsOfURL:url]; - - self.runLoopMode = NSRunLoopCommonModes; - - if(startImmediately) { - [self performAnimations]; - } -} - --(void)loadGifWithData:(nonnull NSData *)imageData { - - self.contentMode = UIViewContentModeScaleAspectFill; - self.clipsToBounds = YES; - self.backgroundColor = [UIColor clearColor]; - self.imageData = imageData; - self.runLoopMode = NSRunLoopCommonModes; - [self performAnimations]; -} - --(void)setImageData:(NSData *)imageData { - _imageData = imageData; -} - --(void) performAnimations{ - self.animatedImage = [[FLAnimatedImage alloc] initWithAnimatedGIFData:self.imageData optimalFrameCacheSize:250 predrawingEnabled:YES]; -} -@end diff --git a/MVMCoreUI/BaseControllers/MFScrollingViewController.m b/MVMCoreUI/BaseControllers/MFScrollingViewController.m index efbf3b9a..f6e2c4d3 100644 --- a/MVMCoreUI/BaseControllers/MFScrollingViewController.m +++ b/MVMCoreUI/BaseControllers/MFScrollingViewController.m @@ -13,10 +13,10 @@ @import MVMCore.NSDictionary_MFConvenience; @import MVMCore.MVMCoreJSONConstants; #import "NSLayoutConstraint+MFConvenience.h" -#import "MFTransparentGIFView.h" #import "MVMCoreUIUtility.h" #import "MVMCoreUIConstants.h" #import "MVMCoreUISession.h" +#import @interface MFScrollingViewController () @@ -299,7 +299,7 @@ static NSTimeInterval const HandScrollAnimationTiming = 7.f; if (!self.gifView) { - MFTransparentGIFView *gifView = [[MFTransparentGIFView alloc] initWithFrame:CGRectZero ImageName:KeyHandScroll StartImmediately:YES Duration:-1 LoopCompletionBlock:nil]; + MFTransparentGIFView *gifView = [[MFTransparentGIFView alloc] initWithFrame:CGRectZero imageName:KeyHandScroll startImmediately:YES duration:-1 loopCompletionBlock:nil]; gifView.translatesAutoresizingMaskIntoConstraints = NO; [self.view addSubview:gifView]; gifView.contentMode = UIViewContentModeScaleAspectFit; diff --git a/MVMCoreUI/BaseControllers/MFViewController.m b/MVMCoreUI/BaseControllers/MFViewController.m index 6bcd4984..1349721d 100644 --- a/MVMCoreUI/BaseControllers/MFViewController.m +++ b/MVMCoreUI/BaseControllers/MFViewController.m @@ -21,13 +21,13 @@ @import MVMCore.NSArray_MFConvenience; @import MVMCore.MVMCoreGetterUtility; @import MVMCore.MVMCoreConstants; +@import MVMCore.MVMCoreCache; #import "NSLayoutConstraint+MFConvenience.h" #import "UIColor+MFConvenience.h" #import "MVMCoreUICommonViewsUtility.h" #import "MFStyler.h" #import "MVMCoreUISplitViewController.h" #import "MVMCoreUITabBarPageControlViewController.h" -#import "MFLoadImageView.h" #import "MFFonts.h" #import #import "MVMCoreUIUtility.h" diff --git a/MVMCoreUI/MVMCoreUI.h b/MVMCoreUI/MVMCoreUI.h index f1fdd0b9..3a8029c4 100644 --- a/MVMCoreUI/MVMCoreUI.h +++ b/MVMCoreUI/MVMCoreUI.h @@ -76,8 +76,6 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[]; #import #import #import -#import -#import #import #import #import diff --git a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m index d05132f4..8583cc2e 100644 --- a/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m +++ b/MVMCoreUI/TopAlert/MVMCoreUITopAlertMainView.m @@ -15,7 +15,7 @@ #import #import "UIColor+MFConvenience.h" #import -#import "MFLoadImageView.h" +#import #import #import "MVMCoreUICommonViewsUtility.h" #import "MVMCoreUITopAlertView.h" @@ -155,7 +155,7 @@ } if (imageURL) { - MFLoadImageView *imageView = [[MFLoadImageView alloc] initWithCenteredImage]; + MFLoadImageView *imageView = [[MFLoadImageView alloc] init]; imageView.translatesAutoresizingMaskIntoConstraints = NO; [imageView setContentCompressionResistancePriority:UILayoutPriorityDefaultHigh forAxis:UILayoutConstraintAxisHorizontal]; [self addSubview:imageView];