UIProgressView
UIProgressView is a UIKit control that displays the progress of a task as a horizontal bar. It is a subclass of UIView and is commonly used to show the completion status of operations like downloads, uploads, or other time-based tasks. This document covers the key properties, methods, and usage of UIProgressView, along with examples and best practices.
Overview of UIProgressView
A UIProgressView visually represents the progress of a task with a bar that fills from left to right. The progress is expressed as a value between 0.0 and 1.0, where 0.0 indicates no progress and 1.0 indicates completion. It is ideal for scenarios where you need to show determinate progress, unlike UIActivityIndicatorView, which is used for indeterminate tasks.
Creating a UIProgressView
You can create a UIProgressView programmatically or via Interface Builder (storyboards/xibs).
Programmatic Example:
import UIKit
let progressView = UIProgressView(progressViewStyle: .default)
progressView.progress = 0.5
progressView.tintColor = .systemBlue
view.addSubview(progressView)Key Properties of UIProgressView
Below are the most commonly used properties of UIProgressView:
| Property | Type | Description |
|---|---|---|
progress | Float | The current progress value (0.0 to 1.0). |
progressTintColor | UIColor? | The color of the filled portion of the progress bar. |
trackTintColor | UIColor? | The color of the unfilled portion of the progress bar. |
progressImage | UIImage? | A custom image for the filled portion of the progress bar. |
trackImage | UIImage? | A custom image for the unfilled portion of the progress bar. |
progressViewStyle | UIProgressView.Style | The style of the progress bar (e.g., .default, .bar). |
Available Styles
.default: A thin progress bar, suitable for general use..bar: A thicker progress bar, often used in navigation or toolbars (e.g., in Safari).
Example: Configuring Properties:
progressView.progress = 0.75
progressView.progressTintColor = .systemGreen
progressView.trackTintColor = .systemGray
progressView.progressViewStyle = .defaultKey Methods of UIProgressView
UIProgressView inherits methods from UIView, but also provides methods specific to progress management:
| Method | Description |
|---|---|
setProgress(_:animated:) | Sets the progress value, optionally animating the change. |
Example: Updating Progress:
progressView.setProgress(0.9, animated: true)Customizing Appearance
Tint Colors
- Use
progressTintColorto set the color of the filled progress bar. - Use
trackTintColorto set the color of the unfilled track.
Example:
progressView.progressTintColor = .systemBlue
progressView.trackTintColor = .systemGray2Custom Images
You can use custom images for the progress and track portions using progressImage and trackImage. This is useful for highly customized designs.
Example:
progressView.progressImage = UIImage(named: "customProgress")
progressView.trackImage = UIImage(named: "customTrack")Notes:
- Images should be resizable or appropriately sized to fit the progress view’s bounds.
- Use
UIGraphicsImageRendererto create custom images programmatically if needed.
Updating Progress
To update the progress, set the progress property or use setProgress(_:animated:). The progress value must be between 0.0 and 1.0.
Example: Simulating Progress:
func simulateProgress() {
var currentProgress: Float = 0.0
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
currentProgress += 0.05
self.progressView.setProgress(currentProgress, animated: true)
if currentProgress >= 1.0 {
timer.invalidate()
}
}
}Best Practices
Use for Determinate Progress: Use
UIProgressViewfor tasks with a known completion percentage; for indeterminate tasks, useUIActivityIndicatorView.Support Accessibility: Set
accessibilityLabelandaccessibilityValuefor VoiceOver.swiftprogressView.accessibilityLabel = "Download progress" progressView.accessibilityValue = "\(Int(progressView.progress * 100))%"Use Auto Layout: Set
translatesAutoresizingMaskIntoConstraints = falseand use constraints (e.g., with SnapKit).Provide Context: Pair with a label to display the progress percentage or status.
Animate Updates: Use
setProgress(_:animated:)for smooth visual transitions.Test on Devices: Verify appearance and animation on various screen sizes and iOS versions.
Troubleshooting
- Progress Not Updating: Ensure
progressis set between 0.0 and 1.0 and the view is added to the view hierarchy. - Appearance Issues: Check iOS version compatibility for properties like
progressTintColor. - Accessibility Issues: Test with VoiceOver to ensure
accessibilityValueupdates dynamically. - Layout Problems: Verify constraints or frame size, as progress views have a fixed height based on their style.
Example: Complete UIProgressView Setup
import UIKit
import SnapKit
class ViewController: UIViewController {
let progressView = UIProgressView(progressViewStyle: .default)
let statusLabel = UILabel()
override func viewDidLoad() {
super.viewDidLoad()
// Configure progress view
progressView.progress = 0.0
progressView.progressTintColor = .systemBlue
progressView.trackTintColor = .systemGray2
progressView.accessibilityLabel = "Download progress"
progressView.accessibilityValue = "0%"
// Configure label
statusLabel.text = "Progress: 0%"
statusLabel.textAlignment = .center
view.addSubview(progressView)
view.addSubview(statusLabel)
// Auto Layout with SnapKit
progressView.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(view.safeAreaLayoutGuide).offset(20)
make.width.equalTo(300)
}
statusLabel.snp.makeConstraints { make in
make.centerX.equalToSuperview()
make.top.equalTo(progressView.snp.bottom).offset(10)
}
// Add tap gesture to simulate progress
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(startProgress))
view.addGestureRecognizer(tapGesture)
}
@objc func startProgress() {
var currentProgress: Float = 0.0
statusLabel.text = "Progress: 0%"
Timer.scheduledTimer(withTimeInterval: 0.1, repeats: true) { timer in
currentProgress += 0.05
self.progressView.setProgress(currentProgress, animated: true)
self.statusLabel.text = "Progress: \(Int(currentProgress * 100))%"
self.progressView.accessibilityValue = "\(Int(currentProgress * 100))%"
if currentProgress >= 1.0 {
timer.invalidate()
self.statusLabel.text = "Completed!"
}
}
}
}