Reputation: 15
So, I have a UIProgressView
in a basic expense tracking app and I want to change its progress tint as it reaches the end from green to red progressively. I don't really know how to do this (I'm just starting out swift and Xcode).
This is how it should roughly work:
My progress is calculated with this line:
let progress = Float(UserDefaults.standard.double(forKey: "spentThisMonth") / UserDefaults.standard.double(forKey: "monthlyExpenseLimit"))
progressView.progress = progress
Here I am dividing the amount the user has spent this month from the limit to get the progress. As the user approaches the limit, the progress tint turns red to indicate that the user should lower their expenditure.
This question is similar but I think its Objective-C, while I use Swift 5. Is there any way to do this, i.e is it possible? I am also new to Stack Overflow so I apologise in advance if I'm doing something wrong.
Upvotes: 1
Views: 1123
Reputation: 77546
You can set the green / red tint color easily by using the progress
value you've already calculated:
let progress = Float(UserDefaults.standard.double(forKey: "spentThisMonth") / UserDefaults.standard.double(forKey: "monthlyExpenseLimit"))
// progress is now a value between 0.0 and 1.0
progressView.progress = progress
let red = CGFloat(progress)
let green = CGFloat(1.0 - progress)
progressView.progressTintColor = UIColor(red: red, green: green, blue: 0.0, alpha: 1.0)
Here's a working example - each time you tap the screen, the progress will increment until it reaches 100%, at which time it will decrement back to Zero:
class ProgressTintViewController: UIViewController {
let progressView = UIProgressView()
let statsLabel = UILabel()
var spentThisMonth: Float = 0
var monthlyExpenseLimit: Float = 100
var isAdding: Bool = true
override func viewDidLoad() {
super.viewDidLoad()
progressView.translatesAutoresizingMaskIntoConstraints = false
statsLabel.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(progressView)
view.addSubview(statsLabel)
let g = view.safeAreaLayoutGuide
NSLayoutConstraint.activate([
progressView.topAnchor.constraint(equalTo: g.topAnchor, constant: 80.0),
progressView.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
progressView.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
statsLabel.topAnchor.constraint(equalTo: progressView.bottomAnchor, constant: 20.0),
statsLabel.leadingAnchor.constraint(equalTo: g.leadingAnchor, constant: 20.0),
statsLabel.trailingAnchor.constraint(equalTo: g.trailingAnchor, constant: -20.0),
])
statsLabel.numberOfLines = 0
let t = UITapGestureRecognizer(target: self, action: #selector(self.tapped))
view.addGestureRecognizer(t)
updateProgress()
}
@objc func tapped() -> Void {
if isAdding {
spentThisMonth += 10
} else {
spentThisMonth -= 10
}
updateProgress()
if spentThisMonth >= monthlyExpenseLimit {
spentThisMonth = monthlyExpenseLimit
isAdding = false
}
if spentThisMonth <= 0 {
spentThisMonth = 0
isAdding = true
}
}
func updateProgress() -> Void {
//let progress = Float(UserDefaults.standard.double(forKey: "spentThisMonth") / UserDefaults.standard.double(forKey: "monthlyExpenseLimit"))
// progress is now a value between 0.0 and 1.0
let progress = spentThisMonth / monthlyExpenseLimit
progressView.progress = progress
let red = CGFloat(progress)
let green = CGFloat(1.0 - progress)
progressView.progressTintColor = UIColor(red: red, green: green, blue: 0.0, alpha: 1.0)
var str = ""
str += "Tap to change progress"
str += "\n\n"
str += "Spent This Month: \(spentThisMonth)"
str += "\n"
str += "Monthly Limit: \(monthlyExpenseLimit)"
str += "\n"
str += "Percent: \(progress)"
statsLabel.text = str
}
}
Upvotes: 1
Reputation: 1215
Sure it can be done using Swift. Here the code from answer made in Swift:
func changeSendProg(progress: CGFloat) {
let redBlueValue: CGFloat = (255 - (255 * progress)) / 255
let colorProg = UIColor(red: redBlueValue, green: redBlueValue, blue: 1.0, alpha: 1.0)
sendProgress.setTintColor(colorProg)
sendProgress.setProgress(progress)
}
Upvotes: 0