diff --git a/Sejima/Sejima.xcodeproj/project.pbxproj b/Sejima/Sejima.xcodeproj/project.pbxproj index 5cc9e06..bdf7eca 100644 --- a/Sejima/Sejima.xcodeproj/project.pbxproj +++ b/Sejima/Sejima.xcodeproj/project.pbxproj @@ -139,6 +139,7 @@ F35A3E052231AA43009341D2 /* MUCardTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F35A3E042231AA43009341D2 /* MUCardTests.swift */; }; F365DD89224D0B710099B628 /* MUActivityIndicatorProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = F365DD88224D0B710099B628 /* MUActivityIndicatorProtocol.swift */; }; F365DD8C224D0BEA0099B628 /* MUActivityIndicatorView.swift in Sources */ = {isa = PBXBuildFile; fileRef = F365DD8B224D0BEA0099B628 /* MUActivityIndicatorView.swift */; }; + F380051822A11E55001FEC90 /* MUCircularProgressType.swift in Sources */ = {isa = PBXBuildFile; fileRef = F380051722A11E55001FEC90 /* MUCircularProgressType.swift */; }; F3A44D2D224232FF00590460 /* MUTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3A44D2B224232FF00590460 /* MUTime.swift */; }; F3A44D2E224232FF00590460 /* MUTime.xib in Resources */ = {isa = PBXBuildFile; fileRef = F3A44D2C224232FF00590460 /* MUTime.xib */; }; F3A44D3022424AC000590460 /* MUTimeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F3A44D2F22424AC000590460 /* MUTimeTests.swift */; }; @@ -310,6 +311,7 @@ F35A3E042231AA43009341D2 /* MUCardTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MUCardTests.swift; sourceTree = ""; }; F365DD88224D0B710099B628 /* MUActivityIndicatorProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MUActivityIndicatorProtocol.swift; sourceTree = ""; }; F365DD8B224D0BEA0099B628 /* MUActivityIndicatorView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MUActivityIndicatorView.swift; sourceTree = ""; }; + F380051722A11E55001FEC90 /* MUCircularProgressType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MUCircularProgressType.swift; sourceTree = ""; }; F3A44D2B224232FF00590460 /* MUTime.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MUTime.swift; sourceTree = ""; }; F3A44D2C224232FF00590460 /* MUTime.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MUTime.xib; sourceTree = ""; }; F3A44D2F22424AC000590460 /* MUTimeTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MUTimeTests.swift; sourceTree = ""; }; @@ -705,6 +707,7 @@ isa = PBXGroup; children = ( F3B377B52232CA2800F07B11 /* MUCircularProgress.swift */, + F380051722A11E55001FEC90 /* MUCircularProgressType.swift */, F3B377B62232CA2800F07B11 /* MUCircularProgress.xib */, ); path = MUCircularProgress; @@ -1061,6 +1064,7 @@ F34BD15A223FDF0400793EDE /* MUNumberSliderCell.swift in Sources */, 6D8BC0D62237EE53006AFE7E /* MUToastPosition.swift in Sources */, 6DDD7E5C22365C780033F5F9 /* MUSegmentedControl.swift in Sources */, + F380051822A11E55001FEC90 /* MUCircularProgressType.swift in Sources */, F35A3DB222310A90009341D2 /* MUSubRangeView.swift in Sources */, F317FF8F2236CD5A001DBDDD /* MUStatData.swift in Sources */, F317FF9F22380191001DBDDD /* MUCollectionItem.swift in Sources */, diff --git a/Sejima/Source/MUCircularProgress/MUCircularProgress.swift b/Sejima/Source/MUCircularProgress/MUCircularProgress.swift index 92e42f7..712ea96 100644 --- a/Sejima/Source/MUCircularProgress/MUCircularProgress.swift +++ b/Sejima/Source/MUCircularProgress/MUCircularProgress.swift @@ -26,6 +26,18 @@ open class MUCircularProgress: MUNibView { @IBOutlet private var labelsLeading: NSLayoutConstraint! @IBOutlet private var labelsTrailing: NSLayoutConstraint! + // MARK: - Style + + /// Define the progress style + open var progressType: MUCircularProgressType = .determinate + + /// Define the progress style (using Int value) + @IBInspectable open dynamic var progressTypeInt: Int = 0 { + didSet { + progressType = MUCircularProgressType(rawValue: progressTypeInt) ?? .determinate + } + } + // MARK: - Icon /// An image displayed. @@ -186,6 +198,12 @@ open class MUCircularProgress: MUNibView { @IBInspectable open dynamic var progressValue: CGFloat = 0.0 { didSet { progressValue = min(progressValue, 1.0) + switch progressType { + case .indeterminate: + startAnimating() + default: + stopAnimating() + } } } @@ -194,6 +212,9 @@ open class MUCircularProgress: MUNibView { /// Specifies the animation duration for the progress line to go from current progress value up to target value. @objc open dynamic var animationDuration: TimeInterval = 0.3 + /// Specifies the animation duration for the indeterminate rotation of the progress line. + @objc open dynamic var rotateDuration: TimeInterval = 1.0 + // MARK: - Private variables private var progressObserver: ((CGFloat) -> Void)? @@ -226,6 +247,14 @@ open class MUCircularProgress: MUNibView { // MARK: - Private method + public func startAnimating() { + rotateAnimation() + } + + public func stopAnimating() { + resetAnimation() + } + private func setupDisplayLink() { displayLink = CADisplayLink(target: MUWeakProxy(self), selector: #selector(observeAnimation)) displayLink?.add(to: .current, forMode: .common) @@ -294,6 +323,24 @@ open class MUCircularProgress: MUNibView { progressObserver?(value) } + // MARK: - Rotate animation + + private func rotateAnimation() { + let animation = CABasicAnimation(keyPath: "transform.rotation") + animation.duration = rotateDuration + animation.repeatCount = MAXFLOAT + animation.byValue = Double.pi * 2 + pathLayer.strokeEnd = progressValue + pathLayer.add(animation, forKey: "rotation") + } + + private func resetAnimation() { + if let transform = pathLayer.presentation()?.transform { + pathLayer.transform = transform + pathLayer.removeAnimation(forKey: "rotation") + } + } + // MARK: - Life cycle functions /// Lays out subviews. diff --git a/Sejima/Source/MUCircularProgress/MUCircularProgressType.swift b/Sejima/Source/MUCircularProgress/MUCircularProgressType.swift new file mode 100644 index 0000000..09830d8 --- /dev/null +++ b/Sejima/Source/MUCircularProgress/MUCircularProgressType.swift @@ -0,0 +1,17 @@ +// +// MUCircularProgressType.swift +// Sejima +// +// Created by Loïc GRIFFIE on 31/05/2019. +// Copyright © 2019 Loïc GRIFFIE. All rights reserved. +// + +import Foundation + +/// Define the type of the circular progress. +public enum MUCircularProgressType: Int { + /// Circular progress with min and max value + case determinate + /// Circular progress with indeterminate loading + case indeterminate +}