Merge branch 'release/7_0' into 'develop'
Release/7 0 See merge request BPHV_MIPS/mvm_core_ui!167
This commit is contained in:
commit
10fe33748f
@ -28,6 +28,8 @@
|
|||||||
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; };
|
0A41BA6E2344FCD400D4C0BC /* CATransaction+Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A41BA6D2344FCD400D4C0BC /* CATransaction+Extension.swift */; };
|
||||||
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
|
0A7BAD74232A8DC700FB8E22 /* HeadlineBodyButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */; };
|
||||||
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; };
|
0A7BAFA1232BE61800FB8E22 /* Checkbox.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */; };
|
||||||
|
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F3236B77BB006A1E82 /* GraphView.swift */; };
|
||||||
|
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */; };
|
||||||
9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; };
|
9455B19C234F8A0400A574DB /* MVMAnimationFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */; };
|
||||||
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; };
|
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */ = {isa = PBXBuildFile; fileRef = 948DB67D2326DCD90011F916 /* MultiProgress.swift */; };
|
||||||
D206997721FB8A0B00CAE0DE /* MVMCoreUINavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
D206997721FB8A0B00CAE0DE /* MVMCoreUINavigationController.h in Headers */ = {isa = PBXBuildFile; fileRef = D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||||
@ -223,6 +225,8 @@
|
|||||||
0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = "<group>"; };
|
0A7BAD73232A8DC700FB8E22 /* HeadlineBodyButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlineBodyButton.swift; sourceTree = "<group>"; };
|
||||||
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = "<group>"; };
|
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Checkbox.swift; sourceTree = "<group>"; };
|
||||||
0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxWithLabelView.swift; sourceTree = "<group>"; };
|
0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CheckboxWithLabelView.swift; sourceTree = "<group>"; };
|
||||||
|
943784F3236B77BB006A1E82 /* GraphView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphView.swift; sourceTree = "<group>"; };
|
||||||
|
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GraphViewAnimationHandler.swift; sourceTree = "<group>"; };
|
||||||
9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = "<group>"; };
|
9455B19B234F8A0400A574DB /* MVMAnimationFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MVMAnimationFramework.framework; path = ../SharedFrameworks/MVMAnimationFramework.framework; sourceTree = "<group>"; };
|
||||||
948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = "<group>"; };
|
948DB67D2326DCD90011F916 /* MultiProgress.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MultiProgress.swift; sourceTree = "<group>"; };
|
||||||
D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUINavigationController.h; sourceTree = "<group>"; };
|
D206997521FB8A0B00CAE0DE /* MVMCoreUINavigationController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MVMCoreUINavigationController.h; sourceTree = "<group>"; };
|
||||||
@ -751,6 +755,8 @@
|
|||||||
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */,
|
0A7BAFA0232BE61800FB8E22 /* Checkbox.swift */,
|
||||||
0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */,
|
0A7BAFA2232BE63400FB8E22 /* CheckboxWithLabelView.swift */,
|
||||||
01004F2F22721C3800991ECC /* RadioButton.swift */,
|
01004F2F22721C3800991ECC /* RadioButton.swift */,
|
||||||
|
943784F3236B77BB006A1E82 /* GraphView.swift */,
|
||||||
|
943784F4236B77BB006A1E82 /* GraphViewAnimationHandler.swift */,
|
||||||
);
|
);
|
||||||
path = Views;
|
path = Views;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@ -1038,6 +1044,7 @@
|
|||||||
isa = PBXSourcesBuildPhase;
|
isa = PBXSourcesBuildPhase;
|
||||||
buildActionMask = 2147483647;
|
buildActionMask = 2147483647;
|
||||||
files = (
|
files = (
|
||||||
|
943784F5236B77BB006A1E82 /* GraphView.swift in Sources */,
|
||||||
D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */,
|
D29DF32121ED0CBA003B2FB9 /* LabelView.m in Sources */,
|
||||||
DBC4391822442197001AB423 /* CaretView.swift in Sources */,
|
DBC4391822442197001AB423 /* CaretView.swift in Sources */,
|
||||||
D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */,
|
D29770F221F7C6D600B2F0D0 /* TopLabelsAndBottomButtonsTableViewController.m in Sources */,
|
||||||
@ -1124,6 +1131,7 @@
|
|||||||
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */,
|
D2E1FADF2268B8E700AEFD8C /* ThreeLayerTableViewController.swift in Sources */,
|
||||||
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */,
|
D20A9A5E2243D3E300ADE781 /* TwoButtonView.swift in Sources */,
|
||||||
D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */,
|
D2B1E3E522F37D6A0065F95C /* ImageHeadlineBody.swift in Sources */,
|
||||||
|
943784F6236B77BB006A1E82 /* GraphViewAnimationHandler.swift in Sources */,
|
||||||
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
|
D29DF2AA21E7B2F9003B2FB9 /* MVMCoreUIConstants.m in Sources */,
|
||||||
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */,
|
948DB67E2326DCD90011F916 /* MultiProgress.swift in Sources */,
|
||||||
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */,
|
D2A5146122121FBF00345BFB /* MoleculeStackTemplate.swift in Sources */,
|
||||||
|
|||||||
280
MVMCoreUI/Atoms/Views/GraphView.swift
Normal file
280
MVMCoreUI/Atoms/Views/GraphView.swift
Normal file
@ -0,0 +1,280 @@
|
|||||||
|
//
|
||||||
|
// GraphView.swift
|
||||||
|
// MobileFirstFramework
|
||||||
|
//
|
||||||
|
// Created by Ryan on 10/24/19.
|
||||||
|
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
|
||||||
|
enum GraphSize: String {
|
||||||
|
case small, medium, large
|
||||||
|
}
|
||||||
|
|
||||||
|
enum GraphStyle: String {
|
||||||
|
case unlimited, safetyMode
|
||||||
|
}
|
||||||
|
|
||||||
|
///Graph Object contains properties
|
||||||
|
public struct GraphObject {
|
||||||
|
|
||||||
|
var style: GraphStyle {
|
||||||
|
didSet {
|
||||||
|
updateStyle()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var size: GraphSize {
|
||||||
|
didSet {
|
||||||
|
updateSize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
var diameter: CGFloat = 24
|
||||||
|
var lineWidth: CGFloat = 5
|
||||||
|
var clockwise: Bool = true
|
||||||
|
var duration : Double = 1.0
|
||||||
|
var colors = [CGColor]()
|
||||||
|
|
||||||
|
public init(_ json: [AnyHashable : Any]?) {
|
||||||
|
style = .unlimited
|
||||||
|
size = .small
|
||||||
|
guard let json = json else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if let styleString = json.optionalStringForKey("style") {
|
||||||
|
style = GraphStyle(rawValue: styleString) ?? .unlimited
|
||||||
|
}
|
||||||
|
if let sizeString = json.optionalStringForKey("size") {
|
||||||
|
size = GraphSize(rawValue: sizeString) ?? .small
|
||||||
|
}
|
||||||
|
updateStyle()
|
||||||
|
updateSize()
|
||||||
|
if let diameter = json.optionalCGFloatForKey("diameter") {
|
||||||
|
self.diameter = diameter
|
||||||
|
}
|
||||||
|
if let lineWidth = json.optionalCGFloatForKey("lineWidth") {
|
||||||
|
self.lineWidth = lineWidth
|
||||||
|
}
|
||||||
|
if let clockwise = json.optionalBoolForKey("clockwise") {
|
||||||
|
self.clockwise = clockwise
|
||||||
|
}
|
||||||
|
if let duration = json["duration"] as? Double {
|
||||||
|
self.duration = duration
|
||||||
|
}
|
||||||
|
if let colorArray = json.optionalArrayForKey("colors") as? [String] {
|
||||||
|
colors = getCGColorsFromArray(colorArray)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCGColorsFromArray(_ colorArray: [String]) -> [CGColor] {
|
||||||
|
return colorArray.map { (colorString) -> CGColor in
|
||||||
|
return UIColor.mfGet(forHex: colorString).cgColor
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mutating func updateStyle() {
|
||||||
|
switch style {
|
||||||
|
case .unlimited:
|
||||||
|
duration = 1.0
|
||||||
|
clockwise = true
|
||||||
|
//current style, only the end part shows darker look
|
||||||
|
colors = getCGColorsFromArray(["#007AB8","#007AB8","#033554"])
|
||||||
|
break
|
||||||
|
case .safetyMode:
|
||||||
|
duration = 1.5
|
||||||
|
clockwise = true
|
||||||
|
colors = getCGColorsFromArray(["#CC4D0F","#CC4D0F","AB0309"])
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//those are
|
||||||
|
mutating func updateSize() {
|
||||||
|
switch size {
|
||||||
|
case .small:
|
||||||
|
diameter = MFSizeObject(standardSize: 24)?.getValueBasedOnApplicationWidth() ?? 24
|
||||||
|
lineWidth = MFSizeObject(standardSize: 5)?.getValueBasedOnApplicationWidth() ?? 5
|
||||||
|
break
|
||||||
|
case .medium:
|
||||||
|
diameter = MFSizeObject(standardSize: 100)?.getValueBasedOnApplicationWidth() ?? 100
|
||||||
|
lineWidth = MFSizeObject(standardSize: 8)?.getValueBasedOnApplicationWidth() ?? 8
|
||||||
|
break
|
||||||
|
case .large:
|
||||||
|
diameter = MFSizeObject(standardSize: 180)?.getValueBasedOnApplicationWidth() ?? 180
|
||||||
|
lineWidth = MFSizeObject(standardSize: 12)?.getValueBasedOnApplicationWidth() ?? 12
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@objcMembers open class GraphView: View {
|
||||||
|
|
||||||
|
var heightConstraint: NSLayoutConstraint?
|
||||||
|
var gradientLayer: CALayer?
|
||||||
|
var graphObject: GraphObject?
|
||||||
|
|
||||||
|
|
||||||
|
// MARK: setup
|
||||||
|
open override func setupView() {
|
||||||
|
super.setupView()
|
||||||
|
//avoid adding height constraint multiple times
|
||||||
|
guard heightConstraint == nil else { return }
|
||||||
|
heightConstraint = heightAnchor.constraint(equalToConstant: 0)
|
||||||
|
heightConstraint?.isActive = true
|
||||||
|
widthAnchor.constraint(equalTo: heightAnchor).isActive = true
|
||||||
|
}
|
||||||
|
|
||||||
|
override open func setWithJSON(_ json: [AnyHashable : Any]?, delegateObject: MVMCoreUIDelegateObject?, additionalData: [AnyHashable : Any]?) {
|
||||||
|
super.setWithJSON(json, delegateObject: delegateObject, additionalData: additionalData)
|
||||||
|
let object = GraphObject(json)
|
||||||
|
graphObject = object
|
||||||
|
createGraphCircle(object)
|
||||||
|
rotationAnimation(object)
|
||||||
|
}
|
||||||
|
|
||||||
|
class func getAngle(_ piValue: Double) -> Double {
|
||||||
|
return piValue / (2.0 * Double.pi) * 360.0
|
||||||
|
}
|
||||||
|
|
||||||
|
class func getPiValue(_ angle: Double) -> Double {
|
||||||
|
return angle / 360.0 * 2.0 * Double.pi
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: circle
|
||||||
|
open func createGraphCircle(_ graphObject: GraphObject) {
|
||||||
|
if let sublayers = layer.sublayers {
|
||||||
|
for sublayer in sublayers {
|
||||||
|
sublayer.removeAllAnimations()
|
||||||
|
sublayer.removeFromSuperlayer()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
heightConstraint?.constant = graphObject.diameter
|
||||||
|
|
||||||
|
//create circle path
|
||||||
|
let radius = graphObject.diameter / 2.0
|
||||||
|
|
||||||
|
//begin point will be at the bottom, clockwise direction
|
||||||
|
let path = UIBezierPath(arcCenter: CGPoint(x: radius
|
||||||
|
, y: radius), radius: radius - graphObject.lineWidth/2.0, startAngle: CGFloat(GraphView.getPiValue(90.0)), endAngle: CGFloat(GraphView.getPiValue(90.0 + 360.0)), clockwise: true)
|
||||||
|
path.lineWidth = graphObject.lineWidth
|
||||||
|
|
||||||
|
let circleLayer = CAShapeLayer()
|
||||||
|
circleLayer.path = path.cgPath
|
||||||
|
circleLayer.lineCap = .round
|
||||||
|
circleLayer.lineWidth = graphObject.lineWidth
|
||||||
|
circleLayer.fillColor = UIColor.clear.cgColor
|
||||||
|
circleLayer.strokeColor = UIColor.black.cgColor
|
||||||
|
|
||||||
|
//create gradient layer
|
||||||
|
let gradientLayer = createGradientLayer(graphObject)
|
||||||
|
gradientLayer.mask = circleLayer
|
||||||
|
layer.addSublayer(gradientLayer)
|
||||||
|
self.gradientLayer = gradientLayer
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
create three gradient layer for circle layout.
|
||||||
|
_____________
|
||||||
|
| → | top layer for smooth gradient
|
||||||
|
-------------
|
||||||
|
| | |
|
||||||
|
| ↑ | ↓ |
|
||||||
|
| | |
|
||||||
|
-------------
|
||||||
|
*/
|
||||||
|
func createGradientLayer(_ graphObject: GraphObject) -> CALayer {
|
||||||
|
let containLayer = CALayer()
|
||||||
|
containLayer.frame = CGRect(x: 0, y: 0, width: graphObject.diameter, height: graphObject.diameter)
|
||||||
|
let radius = graphObject.diameter / 2.0
|
||||||
|
|
||||||
|
//create graident layers
|
||||||
|
guard graphObject.colors.count > 1 else {
|
||||||
|
containLayer.backgroundColor = graphObject.colors.first
|
||||||
|
return containLayer
|
||||||
|
}
|
||||||
|
var topGradientHeight : CGFloat = 0.0
|
||||||
|
var leftColors = graphObject.colors.prefix(through: graphObject.colors.count/2)
|
||||||
|
let rightColors = graphObject.colors.suffix(from: graphObject.colors.count/2)
|
||||||
|
|
||||||
|
// make the top layer higher than line width for smooth look
|
||||||
|
topGradientHeight = min(max(graphObject.lineWidth, 1.0/(1.0+CGFloat(graphObject.colors.count))*graphObject.diameter), graphObject.diameter)
|
||||||
|
let topLayer = CAGradientLayer()
|
||||||
|
topLayer.frame = CGRect(x: 0.0, y: 0.0, width: graphObject.diameter, height: topGradientHeight)
|
||||||
|
//make the graident edge more smoothy
|
||||||
|
topLayer.startPoint = CGPoint(x: 0.25, y: 0.0)
|
||||||
|
topLayer.endPoint = CGPoint(x: 0.75, y: 0.0)
|
||||||
|
//if number of colors is even, need to display gradient layer, otherwise make top layer as solid color layer
|
||||||
|
if graphObject.colors.count % 2 == 0 {
|
||||||
|
leftColors.removeLast()
|
||||||
|
topLayer.colors = [leftColors.last!, rightColors.first!]
|
||||||
|
} else {
|
||||||
|
topLayer.backgroundColor = leftColors.last
|
||||||
|
}
|
||||||
|
containLayer.addSublayer(topLayer)
|
||||||
|
|
||||||
|
let leftLayer = CAGradientLayer()
|
||||||
|
leftLayer.frame = CGRect(x: 0, y: topGradientHeight, width: radius, height: graphObject.diameter - topGradientHeight)
|
||||||
|
leftLayer.startPoint = CGPoint(x: 0, y: 1)
|
||||||
|
leftLayer.endPoint = CGPoint(x: 0, y: 0)
|
||||||
|
|
||||||
|
//count of graidentLayer.colors must be bigger than 1, otherwise set backgroundColor
|
||||||
|
if leftColors.count > 1 {
|
||||||
|
leftLayer.colors = Array(leftColors)
|
||||||
|
} else {
|
||||||
|
leftLayer.backgroundColor = leftColors.first
|
||||||
|
}
|
||||||
|
containLayer.addSublayer(leftLayer)
|
||||||
|
|
||||||
|
let rightLayer = CAGradientLayer()
|
||||||
|
rightLayer.frame = CGRect(x: radius, y: topGradientHeight, width: radius, height: graphObject.diameter - topGradientHeight)
|
||||||
|
rightLayer.startPoint = CGPoint(x: 0, y: 0)
|
||||||
|
rightLayer.endPoint = CGPoint(x: 0, y: 1)
|
||||||
|
if rightColors.count > 1 {
|
||||||
|
rightLayer.colors = Array(rightColors)
|
||||||
|
} else {
|
||||||
|
rightLayer.backgroundColor = rightColors.first
|
||||||
|
}
|
||||||
|
containLayer.addSublayer(rightLayer)
|
||||||
|
|
||||||
|
return containLayer
|
||||||
|
}
|
||||||
|
|
||||||
|
//MARK: Animation
|
||||||
|
func rotationAnimation(_ object: GraphObject) {
|
||||||
|
MVMCoreDispatchUtility.performBlock(onMainThread:{
|
||||||
|
let rotation = CABasicAnimation(keyPath: "transform.rotation")
|
||||||
|
let animationHandler = GraphViewAnimationHandler.shared
|
||||||
|
let startAngle = animationHandler.getAnimationStartAngle(object.duration, CACurrentMediaTime())
|
||||||
|
if startAngle == 0.0 {
|
||||||
|
animationHandler.storeAnimation(object.duration, CACurrentMediaTime())
|
||||||
|
}
|
||||||
|
var fromValue = GraphView.getPiValue(0.0 + startAngle), toValue = GraphView.getPiValue(360.0 + startAngle)
|
||||||
|
if !object.clockwise {
|
||||||
|
fromValue = GraphView.getPiValue(360.0 - startAngle)
|
||||||
|
toValue = GraphView.getPiValue(0.0 - startAngle)
|
||||||
|
}
|
||||||
|
rotation.fromValue = fromValue
|
||||||
|
rotation.toValue = toValue
|
||||||
|
rotation.duration = object.duration
|
||||||
|
rotation.timingFunction = CAMediaTimingFunction(name: .linear)
|
||||||
|
rotation.fillMode = .both
|
||||||
|
rotation.isRemovedOnCompletion = false
|
||||||
|
|
||||||
|
//avoid infinity animation take high CPU momery usage when layer is not displayed
|
||||||
|
rotation.delegate = self
|
||||||
|
rotation.repeatCount = 1
|
||||||
|
self.gradientLayer?.add(rotation, forKey: "rotation")
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
extension GraphView: CAAnimationDelegate {
|
||||||
|
public func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
|
||||||
|
if let object = graphObject {
|
||||||
|
rotationAnimation(object)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
32
MVMCoreUI/Atoms/Views/GraphViewAnimationHandler.swift
Normal file
32
MVMCoreUI/Atoms/Views/GraphViewAnimationHandler.swift
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
//
|
||||||
|
// GraphViewAnimationHandler.swift
|
||||||
|
// MobileFirstFramework
|
||||||
|
//
|
||||||
|
// Created by Ryan on 10/29/19.
|
||||||
|
// Copyright © 2019 Verizon Wireless. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objcMembers open class GraphViewAnimationHandler: NSObject {
|
||||||
|
|
||||||
|
/// duration : CACurrentMediaTime()
|
||||||
|
private var animations = [Double: Double]()
|
||||||
|
|
||||||
|
static let shared = GraphViewAnimationHandler()
|
||||||
|
|
||||||
|
open func storeAnimation(_ duration: Double, _ currentTime: CFTimeInterval) {
|
||||||
|
guard animations[duration] == nil else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
animations[duration] = currentTime
|
||||||
|
}
|
||||||
|
|
||||||
|
open func getAnimationStartAngle(_ duration: Double, _ currentTime: CFTimeInterval) -> Double {
|
||||||
|
if let time = animations[duration] {
|
||||||
|
return (currentTime - time) / duration * 360 + 90
|
||||||
|
}
|
||||||
|
return 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@ -42,6 +42,7 @@
|
|||||||
@"checkboxWithLabelView" : CheckboxWithLabelView.class,
|
@"checkboxWithLabelView" : CheckboxWithLabelView.class,
|
||||||
@"cornerLabels" : CornerLabels.class,
|
@"cornerLabels" : CornerLabels.class,
|
||||||
@"progressbar": ProgressBar.class,
|
@"progressbar": ProgressBar.class,
|
||||||
|
@"circleProgress": GraphView.class,
|
||||||
@"multiProgressBar": MultiProgress.class,
|
@"multiProgressBar": MultiProgress.class,
|
||||||
@"checkbox": MVMCoreUICheckBox.class,
|
@"checkbox": MVMCoreUICheckBox.class,
|
||||||
@"radioButton": RadioButton.class,
|
@"radioButton": RadioButton.class,
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user