Change progress indicator to be a progress bar instead of the activity indicator.

This commit is contained in:
Maurice Parker
2019-04-23 07:26:35 -05:00
parent bf9cfda127
commit 91e009932b
7 changed files with 349 additions and 21 deletions

View File

@@ -0,0 +1,132 @@
//
// NavigationProgressView.swift
// KYNavigationProgress
//
// Created by kyo__hei on 2015/12/29.
// Copyright (c) 2015 kyo__hei. All rights reserved.
//
// Original project: https://github.com/ykyouhei/KYNavigationProgress
import UIKit
public final class NavigationProgressView: UIView {
/* ====================================================================== */
// MARK: - Properties
/* ====================================================================== */
internal var progress: Float = 0 {
didSet {
progress = min(1, progress)
barWidthConstraint.constant = bounds.width * CGFloat(progress)
}
}
internal let bar = UIView()
@objc public dynamic var progressTintColor: UIColor? = UIColor(red: 0, green: 122/255, blue: 1, alpha: 1) {
didSet {
bar.backgroundColor = progressTintColor
}
}
@objc public dynamic var trackTintColor: UIColor? = .clear {
didSet {
backgroundColor = trackTintColor
}
}
fileprivate let barWidthConstraint: NSLayoutConstraint
override public var frame: CGRect {
didSet {
let tmpProgress = progress
progress = tmpProgress
}
}
/* ====================================================================== */
// MARK: - initializer
/* ====================================================================== */
required public init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override init(frame: CGRect) {
barWidthConstraint = NSLayoutConstraint(
item: bar,
attribute: .width,
relatedBy: .equal,
toItem: nil,
attribute: .notAnAttribute,
multiplier: 1,
constant: frame.width * CGFloat(progress))
super.init(frame: frame)
let leftConstraint = NSLayoutConstraint(
item: bar,
attribute: .left,
relatedBy: .equal,
toItem: self,
attribute: .left,
multiplier: 1,
constant: 0)
let bottomConstraint = NSLayoutConstraint(
item: bar,
attribute: .bottom,
relatedBy: .equal,
toItem: self,
attribute: .bottom,
multiplier: 1,
constant: 0)
let topConstraint = NSLayoutConstraint(
item: bar,
attribute: .top,
relatedBy: .equal,
toItem: self,
attribute: .top,
multiplier: 1,
constant: 0)
addSubview(bar)
backgroundColor = trackTintColor
bar.backgroundColor = progressTintColor
bar.translatesAutoresizingMaskIntoConstraints = false
addConstraints([
barWidthConstraint,
leftConstraint,
topConstraint,
bottomConstraint])
}
/* ====================================================================== */
// MARK: - Notification
/* ====================================================================== */
func deviceDidRotate(_ notification: Notification) {
}
/* ====================================================================== */
// MARK: - Method
/* ====================================================================== */
internal func setProgress(_ progress: Float, animated: Bool) {
let duration: TimeInterval = animated ? 0.1 : 0
self.progress = progress
UIView.animate(withDuration: duration, animations: {
self.layoutIfNeeded()
})
}
}

View File

@@ -0,0 +1,27 @@
//
// ProgressTableViewController.swift
// NetNewsWire-iOS
//
// Created by Maurice Parker on 4/23/19.
// Copyright © 2019 Ranchero Software. All rights reserved.
//
import UIKit
class ProgressTableViewController: UITableViewController {
override func viewDidLoad() {
super.viewDidLoad()
NotificationCenter.default.addObserver(self, selector: #selector(progressDidChange(_:)), name: .AccountRefreshProgressDidChange, object: nil)
}
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
navigationController?.updateAccountRefreshProgressIndicator()
}
@objc func progressDidChange(_ note: Notification) {
navigationController?.updateAccountRefreshProgressIndicator()
}
}

View File

@@ -0,0 +1,145 @@
//
// UINavigationController+Progress.swift
// KYNavigationProgress
//
// Created by kyo__hei on 2015/12/29.
// Copyright (c) 2015 kyo__hei. All rights reserved.
//
// Original project: https://github.com/ykyouhei/KYNavigationProgress
import UIKit
import Account
private let constraintIdentifier = "progressHeightConstraint"
public extension UINavigationController {
/* ====================================================================== */
// MARK: - Properties
/* ====================================================================== */
/**
Default is 2.0
*/
var progressHeight: CGFloat {
get { return progressView.frame.height }
set {
progressView.frame.origin.y = navigationBar.frame.height - newValue
progressView.frame.size.height = newValue
}
}
/**
The color shown for the portion of the progress bar that is not filled.
default is clear color.
*/
var trackTintColor: UIColor? {
get { return progressView.trackTintColor }
set { progressView.trackTintColor = newValue }
}
/**
The color shown for the portion of the progress bar that is filled.
default is (r: 0, g: 122, b: 225, a: 255.
*/
var progressTintColor: UIColor? {
get { return progressView.progressTintColor }
set { progressView.progressTintColor = newValue }
}
/**
The current progress is represented by a floating-point value between 0.0 and 1.0,
inclusive, where 1.0 indicates the completion of the task. The default value is 0.0.
*/
var progress: Float {
get { return progressView.progress }
set { progressView.progress = newValue }
}
private var progressView: NavigationProgressView {
for subview in navigationBar.subviews {
if let progressView = subview as? NavigationProgressView {
return progressView
}
}
let defaultHeight = CGFloat(2)
let frame = CGRect(
x: 0,
y: navigationBar.frame.height - defaultHeight,
width: navigationBar.frame.width,
height: defaultHeight
)
let progressView = NavigationProgressView(frame: frame)
navigationBar.addSubview(progressView)
progressView.autoresizingMask = [
.flexibleWidth, .flexibleTopMargin
]
return progressView
}
/* ====================================================================== */
// MARK: - Public Method
/* ====================================================================== */
/**
Adjusts the current progress shown by the receiver, optionally animating the change.
- parameter progress: The new progress value.
- parameter animated: true if the change should be animated, false if the change should happen immediately.
*/
func setProgress(_ progress: Float, animated: Bool) {
progressView.bar.alpha = 1
progressView.setProgress(progress, animated: animated)
}
/**
While progress is changed to 1.0, the bar will fade out. After that, progress will be 0.0.
*/
func finishProgress() {
progressView.bar.alpha = 1
progressView.setProgress(1, animated: true)
UIView.animate(withDuration: 0.25,
animations: {
self.progressView.bar.alpha = 0
}, completion: { finished in
self.progressView.progress = 0
}
)
}
/**
While progress is changed to 0.0, the bar will fade out.
*/
func cancelProgress() {
progressView.setProgress(0, animated: true)
UIView.animate(withDuration: 0.25, animations: {
self.progressView.bar.alpha = 0
})
}
func updateAccountRefreshProgressIndicator() {
let progress = AccountManager.shared.combinedRefreshProgress
if progress.isComplete {
if self.progress != 0 {
finishProgress()
}
} else {
let percent = Float(progress.numberCompleted) / Float(progress.numberOfTasks)
setProgress(percent, animated: true)
}
}
}