Loadimageview to swift
This commit is contained in:
parent
90605d03de
commit
33510a6484
@ -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 = "<group>"; };
|
||||
D22D1F552204CE5D0077CEC0 /* MVMCoreUIStackableViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIStackableViewController.m; sourceTree = "<group>"; };
|
||||
D274CA322236A78900B01B62 /* StandardFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StandardFooterView.swift; sourceTree = "<group>"; };
|
||||
D282AAB3223FDDAE00C46919 /* MFLoadImageView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFLoadImageView.swift; sourceTree = "<group>"; };
|
||||
D282AAB9224131D100C46919 /* MFTransparentGIFView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MFTransparentGIFView.swift; sourceTree = "<group>"; };
|
||||
D28B4F8821FF967C00712C7A /* MVMCoreUIObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUIObject.h; sourceTree = "<group>"; };
|
||||
D28B4F8921FF967C00712C7A /* MVMCoreUIObject.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MVMCoreUIObject.m; sourceTree = "<group>"; };
|
||||
D29770C621F7C4AE00B2F0D0 /* TopLabelsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TopLabelsView.m; sourceTree = "<group>"; };
|
||||
@ -246,10 +246,6 @@
|
||||
D29DF25821E6A22D003B2FB9 /* MFButtonProtocol.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFButtonProtocol.h; sourceTree = "<group>"; };
|
||||
D29DF25A21E6A2B6003B2FB9 /* DashLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DashLine.h; sourceTree = "<group>"; };
|
||||
D29DF25B21E6A2B6003B2FB9 /* DashLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DashLine.m; sourceTree = "<group>"; };
|
||||
D29DF25E21E6A985003B2FB9 /* MFLoadImageView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFLoadImageView.h; sourceTree = "<group>"; };
|
||||
D29DF25F21E6A985003B2FB9 /* MFLoadImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFLoadImageView.m; sourceTree = "<group>"; };
|
||||
D29DF26221E6A9D9003B2FB9 /* MFTransparentGIFView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MFTransparentGIFView.h; sourceTree = "<group>"; };
|
||||
D29DF26321E6A9D9003B2FB9 /* MFTransparentGIFView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MFTransparentGIFView.m; sourceTree = "<group>"; };
|
||||
D29DF26821E6AA0B003B2FB9 /* FLAnimatedImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLAnimatedImage.m; sourceTree = "<group>"; };
|
||||
D29DF26921E6AA0B003B2FB9 /* FLAnimatedImageView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLAnimatedImageView.m; sourceTree = "<group>"; };
|
||||
D29DF26A21E6AA0B003B2FB9 /* FLAnimatedImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FLAnimatedImage.h; sourceTree = "<group>"; };
|
||||
@ -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 */,
|
||||
|
||||
@ -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 <Foundation/Foundation.h>
|
||||
#import <MVMCoreUI/MFTransparentGIFView.h>
|
||||
@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
|
||||
@ -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
|
||||
283
MVMCoreUI/Atoms/Views/MFLoadImageView.swift
Normal file
283
MVMCoreUI/Atoms/Views/MFLoadImageView.swift
Normal file
@ -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())
|
||||
}
|
||||
}
|
||||
@ -1,33 +0,0 @@
|
||||
//
|
||||
// MFTransparentGIFView.h
|
||||
// mobilefirst
|
||||
//
|
||||
// Created by Wesolowski, Brendan on 3/16/16.
|
||||
// Copyright © 2016 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import <MVMCoreUI/FLAnimatedImageView.h>
|
||||
|
||||
@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
|
||||
@ -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
|
||||
@ -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 <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
|
||||
@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;
|
||||
|
||||
@ -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 <MVMCoreUI/MFSizeObject.h>
|
||||
#import "MVMCoreUIUtility.h"
|
||||
|
||||
@ -76,8 +76,6 @@ FOUNDATION_EXPORT const unsigned char MVMCoreUIVersionString[];
|
||||
#import <MVMCoreUI/MFLabel.h>
|
||||
#import <MVMCoreUI/LabelWithInternalButton.h>
|
||||
#import <MVMCoreUI/ViewConstrainingView.h>
|
||||
#import <MVMCoreUI/MFTransparentGIFView.h>
|
||||
#import <MVMCoreUI/MFLoadImageView.h>
|
||||
#import <MVMCoreUI/MFLoadingSpinner.h>
|
||||
#import <MVMCoreUI/MFTextView.h>
|
||||
#import <MVMCoreUI/MFCaretView.h>
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
#import <MVMCore/MVMCoreTopAlertObject.h>
|
||||
#import "UIColor+MFConvenience.h"
|
||||
#import <MVMCore/MVMCoreAlertHandler.h>
|
||||
#import "MFLoadImageView.h"
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
#import <MVMCore/MVMCoreJSONConstants.h>
|
||||
#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];
|
||||
|
||||
Loading…
Reference in New Issue
Block a user