Progress Bar with image pattern mask in SwiftUI


Greetings, traveler!

Expanding on the previous article, I want to demonstrate using image patterns to create a custom progress bar in SwiftUI.

There is an easy way to do this. Following this tutorial, create an Image with a resizable() modifier.

Image(uiImage: image)
    .resizable(resizingMode: .tile)
    .frame(height: imageHeight)

You can also resize a UIKit UIImage to use it with your SwiftUI Image View.

extension UIImage {
    func resized(to size: CGSize) -> UIImage {
        UIGraphicsImageRenderer(size: size).image { _ in
            draw(in: CGRect(origin: .zero, size: size))
        }
    }
}

let image = UIImage(named: "myImage")?.resized(to: patternImageSize) ?? .init()

Then, create a ProgressView and configure it to become a bar. I’m not a huge fan of this approach, but you can adjust the height using the scaleEffect method.

ProgressView(value: progressValue)
    .tint(.pink)
    .scaleEffect(x: 1, y: heightScaleValue, anchor: .center)

Now, you can use your Image as its mask.

ProgressView(value: progressValue)
    .tint(.pink)
    .scaleEffect(x: 1, y: heightScaleValue, anchor: .center)
    .mask {
        Image(uiImage: image)
            .resizable(resizingMode: .tile)
            .frame(height: imageHeight)
    }

Or it’s overlay.

ProgressView(value: progressValue)
    .tint(.pink)
    .scaleEffect(x: 1, y: heightScaleValue, anchor: .center)
    .overlay {
        Image(uiImage: image)
            .resizable(resizingMode: .tile)
            .frame(height: imageHeight)
    }

Conclusion

That’s it! Your Progress bar has become more unique and customizable.