Antidote/Antidote/LinearProgressBar.swift

164 lines
6.4 KiB
Swift

// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.
//
// LinearProgressBar.swift
// CookMinute
//
// Created by Philippe Boisney on 18/11/2015.
// Copyright © 2015 CookMinute. All rights reserved.
//
// Google Guidelines: https://www.google.com/design/spec/components/progress-activity.html#progress-activity-types-of-indicators
//
import UIKit
open class LinearProgressBar: UIView {
//FOR DATA
fileprivate var screenSize: CGRect = UIScreen.main.bounds
fileprivate var isAnimationRunning = false
//FOR DESIGN
fileprivate var progressBarIndicator: UIView!
//PUBLIC VARS
open var backgroundProgressBarColor: UIColor = UIColor(red:0.73, green:0.87, blue:0.98, alpha:1.0)
open var progressBarColor: UIColor = UIColor(red:0.12, green:0.53, blue:0.90, alpha:1.0)
open var heightForLinearBar: CGFloat = 5
open var widthForLinearBar: CGFloat = 0
public init () {
super.init(frame: CGRect(origin: CGPoint(x: 0,y :20), size: CGSize(width: screenSize.width, height: 0)))
self.progressBarIndicator = UIView(frame: CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: 0, height: heightForLinearBar)))
}
override public init(frame: CGRect) {
super.init(frame: frame)
self.progressBarIndicator = UIView(frame: CGRect(origin: CGPoint(x: 0,y :0), size: CGSize(width: 0, height: heightForLinearBar)))
}
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//MARK: LIFE OF VIEW
override open func layoutSubviews() {
super.layoutSubviews()
self.screenSize = UIScreen.main.bounds
if widthForLinearBar == 0 || widthForLinearBar == self.screenSize.height {
widthForLinearBar = self.screenSize.width
}
if (UIDeviceOrientationIsLandscape(UIDevice.current.orientation)) {
self.frame = CGRect(origin: CGPoint(x: self.frame.origin.x,y :self.frame.origin.y), size: CGSize(width: widthForLinearBar, height: self.frame.height))
}
if (UIDeviceOrientationIsPortrait(UIDevice.current.orientation)) {
self.frame = CGRect(origin: CGPoint(x: self.frame.origin.x,y :self.frame.origin.y), size: CGSize(width: widthForLinearBar, height: self.frame.height))
}
}
//MARK: PUBLIC FUNCTIONS ------------------------------------------------------------------------------------------
//Start the animation
open func startAnimation(viewToAddto: UIView, viewToAlignToBottomOf: UIView, bottom_margin: Int ){
self.configureColors()
self.show(viewToAddto: viewToAddto, viewToAlignToBottomOf: viewToAlignToBottomOf, bottom_margin: bottom_margin)
if !isAnimationRunning {
self.isAnimationRunning = true
UIView.animate(withDuration: 0.5, delay:0, options: [], animations: {
self.frame = CGRect(x: 0, y: self.frame.origin.y, width: self.widthForLinearBar, height: self.heightForLinearBar)
}, completion: { animationFinished in
self.addSubview(self.progressBarIndicator)
self.configureAnimation()
})
}
}
//Start the animation
open func stopAnimation() {
self.isAnimationRunning = false
UIView.animate(withDuration: 0.5, animations: {
self.progressBarIndicator.frame = CGRect(x: 0, y: 0, width: self.widthForLinearBar, height: 0)
self.frame = CGRect(x: 0, y: self.frame.origin.y, width: self.widthForLinearBar, height: 0)
})
}
//MARK: PRIVATE FUNCTIONS ------------------------------------------------------------------------------------------
fileprivate func show(viewToAddto: UIView, viewToAlignToBottomOf: UIView, bottom_margin: Int ) {
// Only show once
if self.superview != nil {
return
}
// Find current top viewcontroller
if let topController = getTopViewController() {
// let superView: UIView = topController.view
viewToAddto.addSubview(self)
// update: show progressbar in the vertical center of the screen
self.snp.makeConstraints { make in
make.leading.trailing.equalToSuperview()
make.top.equalTo(viewToAlignToBottomOf.snp.bottom).offset(bottom_margin)
}
}
}
fileprivate func configureColors(){
self.backgroundColor = self.backgroundProgressBarColor
self.progressBarIndicator.backgroundColor = self.progressBarColor
self.layoutIfNeeded()
}
fileprivate func configureAnimation() {
guard let superview = self.superview else {
stopAnimation()
return
}
self.progressBarIndicator.frame = CGRect(origin: CGPoint(x: 0, y :0), size: CGSize(width: 0, height: heightForLinearBar))
UIView.animateKeyframes(withDuration: 1.0, delay: 0, options: [], animations: {
UIView.addKeyframe(withRelativeStartTime: 0, relativeDuration: 0.5, animations: {
self.progressBarIndicator.frame = CGRect(x: 0, y: 0, width: self.widthForLinearBar*0.7, height: self.heightForLinearBar)
})
UIView.addKeyframe(withRelativeStartTime: 0.5, relativeDuration: 0.5, animations: {
self.progressBarIndicator.frame = CGRect(x: superview.frame.width, y: 0, width: 0, height: self.heightForLinearBar)
})
}) { (completed) in
if (self.isAnimationRunning){
self.configureAnimation()
}
}
}
// -----------------------------------------------------
//MARK: UTILS ---------------------------------------
// -----------------------------------------------------
fileprivate func getTopViewController() -> UIViewController? {
var topController: UIViewController? = UIApplication.shared.keyWindow?.rootViewController
while topController?.presentedViewController != nil {
topController = topController?.presentedViewController
}
return topController
}
}