refactored loader
Signed-off-by: Matt Bruce <matt.bruce@verizon.com>
This commit is contained in:
parent
6a8e45fc9e
commit
c03e04069a
@ -298,8 +298,8 @@
|
||||
AFA4935729EE3DCC001A9663 /* AlertDelegateProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */; };
|
||||
AFE4A1D127DFB5EE00C458D0 /* VDSColorTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFE4A1D027DFB5EE00C458D0 /* VDSColorTokens.xcframework */; };
|
||||
AFE4A1D627DFBB6F00C458D0 /* UINavigationController+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */; };
|
||||
B4CC8FBF29DF34730005D28B /* BadgeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBE29DF34730005D28B /* BadgeModel.swift */; };
|
||||
B4CC8FBD29DF34680005D28B /* Badge.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBC29DF34680005D28B /* Badge.swift */; };
|
||||
B4CC8FBF29DF34730005D28B /* BadgeModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = B4CC8FBE29DF34730005D28B /* BadgeModel.swift */; };
|
||||
BB105859248DEFF70069D008 /* UICollectionViewLeftAlignedLayout.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */; };
|
||||
BB1D17E0244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */; };
|
||||
BB1D17E2244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift in Sources */ = {isa = PBXBuildFile; fileRef = BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */; };
|
||||
@ -576,8 +576,8 @@
|
||||
EA5124FF2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA5124FE2436018E0051A3A4 /* BGImageHeadlineBodyButtonModel.swift */; };
|
||||
EA7E67742758310500ABF773 /* EnableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67732758310500ABF773 /* EnableFormFieldEffectModel.swift */; };
|
||||
EA7E67762758365300ABF773 /* UIUpdatableModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA7E67752758365300ABF773 /* UIUpdatableModelProtocol.swift */; };
|
||||
EA985C402970939A00F2FF2E /* TileletModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3F2970939A00F2FF2E /* TileletModel.swift */; };
|
||||
EA985C3E2970938F00F2FF2E /* Tilelet.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3D2970938F00F2FF2E /* Tilelet.swift */; };
|
||||
EA985C402970939A00F2FF2E /* TileletModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C3F2970939A00F2FF2E /* TileletModel.swift */; };
|
||||
EA985C602970A3F000F2FF2E /* VDS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA985C5F2970A3F000F2FF2E /* VDS.framework */; };
|
||||
EA985C642970A40E00F2FF2E /* VDSTypographyTokens.xcframework in Frameworks */ = {isa = PBXBuildFile; fileRef = EA985C632970A40E00F2FF2E /* VDSTypographyTokens.xcframework */; };
|
||||
EA985C852981AA9C00F2FF2E /* VDS-Enums+Codable.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA985C842981AA9C00F2FF2E /* VDS-Enums+Codable.swift */; };
|
||||
@ -587,6 +587,7 @@
|
||||
EAA0CFAF275E7D8000D65EB0 /* FormFieldEffectProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */; };
|
||||
EAA0CFB1275E823A00D65EB0 /* HideFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */; };
|
||||
EAA0CFB3275E831E00D65EB0 /* DisableFormFieldEffectModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */; };
|
||||
EAA482CE2B45F2F300978105 /* MFLoadingSpinner+VDS.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA482CD2B45F2F300978105 /* MFLoadingSpinner+VDS.swift */; };
|
||||
EAA78020290081320057DFDF /* VDSMoleculeViewProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAA7801F290081320057DFDF /* VDSMoleculeViewProtocol.swift */; };
|
||||
EAB14BC127D935F00012AB2C /* RuleCompareModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB14BC027D935F00012AB2C /* RuleCompareModelProtocol.swift */; };
|
||||
EAB14BC327D9378D0012AB2C /* RuleAnyModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAB14BC227D9378D0012AB2C /* RuleAnyModelProtocol.swift */; };
|
||||
@ -890,8 +891,8 @@
|
||||
AFA4935629EE3DCC001A9663 /* AlertDelegateProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertDelegateProtocol.swift; sourceTree = "<group>"; };
|
||||
AFE4A1D027DFB5EE00C458D0 /* VDSColorTokens.xcframework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcframework; name = VDSColorTokens.xcframework; path = ../SharedFrameworks/VDSColorTokens.xcframework; sourceTree = "<group>"; };
|
||||
AFE4A1D527DFBB6F00C458D0 /* UINavigationController+Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UINavigationController+Extension.swift"; sourceTree = "<group>"; };
|
||||
B4CC8FBE29DF34730005D28B /* BadgeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeModel.swift; sourceTree = "<group>"; };
|
||||
B4CC8FBC29DF34680005D28B /* Badge.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Badge.swift; sourceTree = "<group>"; };
|
||||
B4CC8FBE29DF34730005D28B /* BadgeModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BadgeModel.swift; sourceTree = "<group>"; };
|
||||
BB105858248DEFF60069D008 /* UICollectionViewLeftAlignedLayout.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UICollectionViewLeftAlignedLayout.swift; sourceTree = "<group>"; };
|
||||
BB1D17DF244EAA30001D2002 /* ListDeviceComplexButtonMediumModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMediumModel.swift; sourceTree = "<group>"; };
|
||||
BB1D17E1244EAA46001D2002 /* ListDeviceComplexButtonMedium.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ListDeviceComplexButtonMedium.swift; sourceTree = "<group>"; };
|
||||
@ -1180,6 +1181,7 @@
|
||||
EAA0CFAE275E7D8000D65EB0 /* FormFieldEffectProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FormFieldEffectProtocol.swift; sourceTree = "<group>"; };
|
||||
EAA0CFB0275E823A00D65EB0 /* HideFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HideFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
||||
EAA0CFB2275E831E00D65EB0 /* DisableFormFieldEffectModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisableFormFieldEffectModel.swift; sourceTree = "<group>"; };
|
||||
EAA482CD2B45F2F300978105 /* MFLoadingSpinner+VDS.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "MFLoadingSpinner+VDS.swift"; sourceTree = "<group>"; };
|
||||
EAA7801F290081320057DFDF /* VDSMoleculeViewProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = VDSMoleculeViewProtocol.swift; sourceTree = "<group>"; };
|
||||
EAB14BC027D935F00012AB2C /* RuleCompareModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleCompareModelProtocol.swift; sourceTree = "<group>"; };
|
||||
EAB14BC227D9378D0012AB2C /* RuleAnyModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleAnyModelProtocol.swift; sourceTree = "<group>"; };
|
||||
@ -1635,6 +1637,7 @@
|
||||
D20492A324329A2800A5EED6 /* MVMCoreUIPagingProtocol.h */,
|
||||
D29DF2B121E7B76C003B2FB9 /* MFLoadingSpinner.h */,
|
||||
D29DF2B221E7B76D003B2FB9 /* MFLoadingSpinner.m */,
|
||||
EAA482CD2B45F2F300978105 /* MFLoadingSpinner+VDS.swift */,
|
||||
D29DF25821E6A22D003B2FB9 /* MFButtonProtocol.h */,
|
||||
D29DF16B21E69E1F003B2FB9 /* ButtonDelegateProtocol.h */,
|
||||
);
|
||||
@ -2689,6 +2692,7 @@
|
||||
0A6682A42434DB8D00AD3CA1 /* ListLeftVariableRadioButtonBodyTextModel.swift in Sources */,
|
||||
AA2AD116244EE46800BBFFE3 /* ListDeviceComplexLinkMedium.swift in Sources */,
|
||||
AA7F32AD246C0F8C00C965BA /* ListLeftVariableRadioButtonAllTextAndLinks.swift in Sources */,
|
||||
EAA482CE2B45F2F300978105 /* MFLoadingSpinner+VDS.swift in Sources */,
|
||||
D272F5F92473163100BD1A8F /* BarButtonItem.swift in Sources */,
|
||||
D2D2FCF3252B72CF0033EAAA /* MoleculeSectionFooter.swift in Sources */,
|
||||
0A9D09202433796500D2E6C0 /* BarsIndicatorView.swift in Sources */,
|
||||
|
||||
@ -117,7 +117,7 @@
|
||||
spinnerHeight = constraint.constant
|
||||
loadingSpinnerHeightConstraint?.constant = 0
|
||||
loadingSpinnerHeightConstraint?.isActive = true
|
||||
loadingSpinner.pause()
|
||||
loadingSpinner.pauseSpinner()
|
||||
}
|
||||
}
|
||||
|
||||
@ -326,7 +326,7 @@
|
||||
guard let self = self,
|
||||
let loadingImageName = self.currentImageName, loadingImageName == imageName else { return }
|
||||
self.isFallbackImage = isFallbackImage
|
||||
self.loadingSpinner.pause()
|
||||
self.loadingSpinner.pauseSpinner()
|
||||
let layoutWillChange = self.shouldNotifyDelegateOnUpdate ? self.layoutWillChange(width: self.currentImageWidth, height: self.currentImageHeight, size: image?.size) : false
|
||||
self.addConstraints(width: width, height: height, size: image?.size)
|
||||
self.loadingSpinnerHeightConstraint?.constant = 0
|
||||
@ -359,7 +359,7 @@
|
||||
return
|
||||
}
|
||||
self?.loadingSpinnerHeightConstraint?.constant = 0
|
||||
self?.loadingSpinner.pause()
|
||||
self?.loadingSpinner.pauseSpinner()
|
||||
if flipImage, let cgImage = image.cgImage {
|
||||
self?.imageView.image = UIImage(cgImage: cgImage, scale: image.scale, orientation: UIImage.Orientation.upMirrored)
|
||||
} else {
|
||||
|
||||
@ -122,7 +122,7 @@ extension WebView : WKUIDelegate {
|
||||
public func webView(_ webView: WKWebView, didFinish navigation: WKNavigation!) {
|
||||
// hide loading
|
||||
overLayer.isHidden = true
|
||||
loadingSpinner.pause()
|
||||
loadingSpinner.pauseSpinner()
|
||||
|
||||
//update webview's heigth when webview is ready
|
||||
if !dynamicHeight {
|
||||
@ -159,7 +159,7 @@ extension WebView : WKUIDelegate {
|
||||
//actually no error handle page show in webview. We can handle the error display view by our self.
|
||||
//or stop loading by default
|
||||
overLayer.isHidden = true
|
||||
loadingSpinner.pause()
|
||||
loadingSpinner.pauseSpinner()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
42
MVMCoreUI/Legacy/Views/MFLoadingSpinner+VDS.swift
Normal file
42
MVMCoreUI/Legacy/Views/MFLoadingSpinner+VDS.swift
Normal file
@ -0,0 +1,42 @@
|
||||
//
|
||||
// MFLoadingSpinner+VDS.swift
|
||||
// MVMCoreUI
|
||||
//
|
||||
// Created by Matt Bruce on 1/3/24.
|
||||
// Copyright © 2024 Verizon Wireless. All rights reserved.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import VDS
|
||||
|
||||
extension MFLoadingSpinner {
|
||||
var loader: Loader? {
|
||||
subviews.first as? Loader
|
||||
}
|
||||
|
||||
@objc(setUpCircle:)
|
||||
open func setUpCircle(strokeColor: UIColor?) {
|
||||
if let strokeColor {
|
||||
loader?.surface = strokeColor.isDark() ? .light : .dark
|
||||
}
|
||||
}
|
||||
|
||||
@objc open func pauseSpinner() {
|
||||
loader?.isActive = false
|
||||
}
|
||||
|
||||
@objc open func resumeSpinner() {
|
||||
loader?.isActive = true
|
||||
}
|
||||
|
||||
@objc open func resumeSpinnerAfterDelay() {
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.3) { [weak self] in
|
||||
self?.loader?.isActive = true
|
||||
}
|
||||
}
|
||||
|
||||
@objc open func pinWidthAndHeight() -> NSDictionary? {
|
||||
guard let size = loader?.size else { return nil }
|
||||
return NSLayoutConstraint.constraintPinView(self, heightConstraint: true, heightConstant: CGFloat(size), widthConstraint: true, widthConstant: CGFloat(size)) as NSDictionary?
|
||||
}
|
||||
}
|
||||
@ -12,17 +12,6 @@
|
||||
|
||||
-(void)setUpCircle;
|
||||
|
||||
-(void)setUpCircle:(nullable UIColor *)strokeColor;
|
||||
|
||||
-(void)changeColor:(nullable UIColor *)strokeColor;
|
||||
|
||||
- (void)pauseSpinner;
|
||||
|
||||
- (void)resumeSpinner;
|
||||
|
||||
// Starts the spinner after a slight delay.
|
||||
- (void)resumeSpinnerAfterDelay;
|
||||
|
||||
- (nullable NSDictionary *)pinWidthAndHeight;
|
||||
|
||||
@end
|
||||
|
||||
@ -7,143 +7,33 @@
|
||||
//
|
||||
|
||||
#import "MFLoadingSpinner.h"
|
||||
#import "UIColor+MFConvenience.h"
|
||||
#import "NSLayoutConstraint+MFConvenience.h"
|
||||
#import <VDS/VDS.h>
|
||||
#import <MVMCoreUI/MVMCoreUI-Swift.h>
|
||||
|
||||
@interface MFLoadingSpinner ()
|
||||
|
||||
@property (strong, nonatomic) CAShapeLayer *myCircle;
|
||||
@property (strong, nonatomic) CADisplayLink *myDisplay;
|
||||
@property (weak, nonatomic) dispatch_block_t resumeBlock;
|
||||
|
||||
@property (nonatomic) double prevFrame;
|
||||
|
||||
@property (nonatomic) BOOL isFast;
|
||||
|
||||
@property (strong, nonatomic) VDSLoader *loader;
|
||||
@end
|
||||
|
||||
@implementation MFLoadingSpinner
|
||||
|
||||
|
||||
|
||||
|
||||
const float radius = 19;
|
||||
const float lineWidth = 3.0;
|
||||
const float slowSpeed = 0.5;
|
||||
const float fastSpeed = 2.0;
|
||||
const float startSpeed = 1.0;
|
||||
const float fastDistance = .45;
|
||||
const float slowDistance = 0.1;
|
||||
|
||||
|
||||
-(void)finalize {
|
||||
[self.myDisplay invalidate];
|
||||
self.myDisplay = nil;
|
||||
- (instancetype)initWithFrame:(CGRect)frame
|
||||
{
|
||||
self = [super initWithFrame:frame];
|
||||
if (self) {
|
||||
self.loader = [[VDSLoader alloc] init];
|
||||
[self addSubview: self.loader];
|
||||
[NSLayoutConstraint pinViewToSuperview:self.loader useMargins:false];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
-(void)setUpCircle {
|
||||
[self setUpCircle:[UIColor blackColor]];
|
||||
}
|
||||
|
||||
-(void)setUpCircle:(UIColor *)strokeColor {
|
||||
if(self.myCircle)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
CAShapeLayer *circle = [CAShapeLayer layer];
|
||||
circle.path = [UIBezierPath bezierPathWithArcCenter:CGPointMake(radius + lineWidth/2, radius + lineWidth/2) radius:radius startAngle:-M_PI_2 endAngle:3.5*M_PI clockwise:YES].CGPath;
|
||||
circle.lineWidth = lineWidth;
|
||||
circle.fillColor = [UIColor clearColor].CGColor;
|
||||
circle.strokeColor = strokeColor.CGColor;
|
||||
circle.lineCap = kCALineCapButt;
|
||||
circle.strokeStart = 0;
|
||||
circle.strokeEnd = 0+.05;
|
||||
[self.layer addSublayer:circle];
|
||||
self.myCircle = circle;
|
||||
|
||||
self.isFast = YES;
|
||||
|
||||
NSMutableDictionary *newActions = [[NSMutableDictionary alloc] initWithObjectsAndKeys:[NSNull null], @"strokeStart",
|
||||
[NSNull null], @"strokeEnd",
|
||||
[NSNull null], @"strokeColor",
|
||||
nil];
|
||||
circle.actions = newActions;
|
||||
|
||||
self.myDisplay = [CADisplayLink displayLinkWithTarget:self selector:@selector(updateSpinner)];
|
||||
[self.myDisplay addToRunLoop:[NSRunLoop mainRunLoop] forMode:NSRunLoopCommonModes];
|
||||
self.myDisplay.frameInterval = 2;
|
||||
self.prevFrame = CACurrentMediaTime();
|
||||
[self setUpCircle:[UIColor blackColor]];
|
||||
}
|
||||
|
||||
-(void)changeColor:(UIColor *)strokeColor {
|
||||
self.myCircle.strokeColor = strokeColor.CGColor;
|
||||
}
|
||||
|
||||
-(void)updateSpinner {
|
||||
double currentTime = CACurrentMediaTime();
|
||||
double renderTime = currentTime - self.prevFrame;
|
||||
self.prevFrame = currentTime;
|
||||
|
||||
if(self.myCircle.strokeStart > 0.5 && self.myCircle.strokeEnd > 0.5) {
|
||||
self.myCircle.strokeStart -= 0.5;
|
||||
self.myCircle.strokeEnd -= 0.5;
|
||||
}
|
||||
|
||||
float distanceToStart = self.myCircle.strokeEnd - self.myCircle.strokeStart;
|
||||
if(distanceToStart < slowDistance && !self.isFast) {
|
||||
self.isFast = YES;
|
||||
}
|
||||
else if(distanceToStart > fastDistance && self.isFast) {
|
||||
self.isFast = NO;
|
||||
}
|
||||
self.myCircle.strokeEnd += (self.isFast ? fastSpeed : slowSpeed) * renderTime;
|
||||
self.myCircle.strokeStart+= startSpeed * renderTime;
|
||||
|
||||
}
|
||||
|
||||
- (void)pauseSpinner {
|
||||
if (self.resumeBlock) {
|
||||
// Cancel the current resume block if it hasn't run. dispatch our pause into the same queue incase the resume block is already running.
|
||||
dispatch_block_cancel(self.resumeBlock);
|
||||
self.resumeBlock = nil;
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
weakSelf.myDisplay.paused = YES;
|
||||
weakSelf.hidden = YES;
|
||||
});
|
||||
} else {
|
||||
self.myDisplay.paused = YES;
|
||||
self.hidden = YES;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)resumeSpinner {
|
||||
self.hidden = NO;
|
||||
if (!self.myCircle) {
|
||||
[self setUpCircle];
|
||||
return;
|
||||
}
|
||||
|
||||
self.myDisplay.paused = NO;
|
||||
self.prevFrame = CACurrentMediaTime();
|
||||
}
|
||||
|
||||
- (void)resumeSpinnerAfterDelay {
|
||||
if (!self.resumeBlock) {
|
||||
__weak typeof(self) weakSelf = self;
|
||||
dispatch_block_t resume = dispatch_block_create(0, ^{
|
||||
[weakSelf resumeSpinner];
|
||||
weakSelf.resumeBlock = nil;
|
||||
});
|
||||
self.resumeBlock = resume;
|
||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.3 * NSEC_PER_SEC)), dispatch_get_main_queue(), resume);
|
||||
}
|
||||
}
|
||||
|
||||
- (nullable NSDictionary *)pinWidthAndHeight {
|
||||
CGFloat diameter = radius*2 + lineWidth;
|
||||
return [NSLayoutConstraint constraintPinView:self heightConstraint:YES heightConstant:diameter widthConstraint:YES widthConstant:diameter];
|
||||
[self setUpCircle: strokeColor];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
Loading…
Reference in New Issue
Block a user