164 lines
6.4 KiB
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
|
|
}
|
|
}
|