Skip to content

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:

swift
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:

PropertyTypeDescription
progressFloatThe current progress value (0.0 to 1.0).
progressTintColorUIColor?The color of the filled portion of the progress bar.
trackTintColorUIColor?The color of the unfilled portion of the progress bar.
progressImageUIImage?A custom image for the filled portion of the progress bar.
trackImageUIImage?A custom image for the unfilled portion of the progress bar.
progressViewStyleUIProgressView.StyleThe 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:

swift
progressView.progress = 0.75
progressView.progressTintColor = .systemGreen
progressView.trackTintColor = .systemGray
progressView.progressViewStyle = .default

Key Methods of UIProgressView

UIProgressView inherits methods from UIView, but also provides methods specific to progress management:

MethodDescription
setProgress(_:animated:)Sets the progress value, optionally animating the change.

Example: Updating Progress:

swift
progressView.setProgress(0.9, animated: true)

Customizing Appearance

Tint Colors

  • Use progressTintColor to set the color of the filled progress bar.
  • Use trackTintColor to set the color of the unfilled track.

Example:

swift
progressView.progressTintColor = .systemBlue
progressView.trackTintColor = .systemGray2

Custom Images

You can use custom images for the progress and track portions using progressImage and trackImage. This is useful for highly customized designs.

Example:

swift
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 UIGraphicsImageRenderer to 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:

swift
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 UIProgressView for tasks with a known completion percentage; for indeterminate tasks, use UIActivityIndicatorView.

  • Support Accessibility: Set accessibilityLabel and accessibilityValue for VoiceOver.

    swift
    progressView.accessibilityLabel = "Download progress"
    progressView.accessibilityValue = "\(Int(progressView.progress * 100))%"
  • Use Auto Layout: Set translatesAutoresizingMaskIntoConstraints = false and 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 progress is 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 accessibilityValue updates dynamically.
  • Layout Problems: Verify constraints or frame size, as progress views have a fixed height based on their style.

Example: Complete UIProgressView Setup

swift
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!"
            }
        }
    }
}

Resources

Released under the MIT License.