How to operate. Create a custom ProgressView with SwiftUI

Martin Albrecht

Focus on

On June 27

– 4 minutes to read

Photo: Nick PageonUnsplash

For creating a progress bar view in an iOS or MacOS application, you may already be familiar with the ProgressView element in UIKit or SwiftUI, or you may know that it lacks simple customization. The default implementation is just a thin bar filled with blue.

The default ProgressView

Custom view modifiers, such as _ background _, height, and so on, will change everything about the view except the bar itself.

It will stay the way it is — blue and plain.

If you want to have your own custom progress bar, you have two options.

  1. Create your own progress bar view and implement it
  2. Create your own custom progress bar view style using the ProgressViewStyle protocol provided by Apple.

This article focuses on the latter, although you could just as easily take the code, extend it with bindings, and have your own view instead of style — it just doesn’t make sense at all.

Extending an existing protocol should also be the preferred approach, since reinventing the wheel is rarely a good idea.

The target

As always, let’s see what we ultimately want to achieve.

The final progress view we want to implement

We want to have a wider blue bar instead of a solid color gradient bar. In addition, we want to be able to set an optional label that appears at the bottom of the view.

agreement

Apple provides us with a protocol for creating custom process view styles in SwiftUI. ProgressViewStyle.

The protocol itself has a method requirement.

func makeBody(configuration: Self.Configuration) -> Self.Body

This function basically sets up our custom progress view. In it, we define the body of the View and any attributes, styles, etc. — in fact, it’s very similar to the Func Body (Content: Content) -> some View function of the ViewModifier protocol. If you know ViewModifier, it should be very easy to apply that knowledge to style agreements.

style

Creating a custom progress view style means basically defining the entire view body, not just the style.

For the body of our progress view style, we use a ZStack and wrap it in a VStack to get the possibility of labels. In addition, we added some variables to get some custom options (such as background, height, etc.).

Lines 4-9 are the properties that are used to customize our custom view. Most of our properties have default values, so only _ stroke _ and _ fill _ are required, the rest are optional.

Inside the ZStack, we placed an GeometryReader to dynamically read the width of the view, which we then applied to the enclosing rectangle width based on the current value of the progress view. If the user rotates the screen or changes the view’s resolution, the status of the progress bar should be the same, but scaled to the new width.

The current value of the progress bar can be read from the given configuration object in the makeBody function. _configuration. FractionCompleted _ value represents the fraction of the overall work done, is a Double value from 0 to 1.

implementation

Let’s take a look at how to implement our custom progress bar. We’ll replace the static value of the progress bar with a Slider view that defines the status of the progress bar. With it, we can change the progress bar dynamically.

To keep things simple, we’ll just use the contentView.swift file — in real life it might be better to split it up into separate files.

ContentView.swift

The first line (3-36) is the style of the progress bar we used in the previous section.

Lines 39-75 are the implementation itself. As usual, it should be very direct. First, we define some state variables for the value, the input state (for our slider), and the gradient we want for the progress bar.

In lines 59-61, you can see the implementation of the ProgressView, with our custom styles and some vertical padding. Not too many bells and whistles…

If we run the code and turn the slider handle, our progress bar will look exactly like the one we saw above. This method should give us some basic concepts for creating custom progress bars, so you can now easily create your own, or just take the code from here and extend it.