Segmented Progress Bar on iOS with UIKit
Step-by-step guide on implementing a segmented progress bar on iOS with UIKit
Introduction
In this tutorial, we will walk you through the step-by-step process of creating a segmented progress bar using UIKit. This segmented bar can be used to display progress or indicate steps in a process, enhancing the user experience in your iOS applications.
Step 1: Create a New UIView Subclass
First, create a new UIView
subclass named SegmentBarView
. This will be the main component for our segmented progress bar.
import UIKit
final class SegmentBarView: UIView {
}
Step 2: Define the Model
Define a Model
struct inside the SegmentBarView
to hold the configuration for the segmented bar. This struct will include an array of colors and a spacing value.
import UIKit
final class SegmentBarView: UIView {
// MARK: - Model
struct Model {
let colors: [UIColor]
let spacing: CGFloat
}
private var model: Model?
}
Step 3: Add a Method to Set the Model
Create a method to set the model and update the view’s subviews based on the model’s colors.
import UIKit
final class SegmentBarView: UIView {
// MARK: - Model
struct Model {
let colors: [UIColor]
let spacing: CGFloat
}
private var model: Model?
func setModel(_ model: Model) {
self.model = model
subviews.forEach { $0.removeFromSuperview() }
let views = model.colors.map {
let view = UIView()
view.backgroundColor = $0
view.cornerRadius = 3
return view
}
views.forEach { addSubview($0) }
setNeedsLayout()
}
}
Step 3: Calculate Segment Width
Let’s create a helper function to calculate the width of each segment based on the available width, total segments, and spacing between them.
import UIKit
final class SegmentBarView: UIView {
// MARK: - Model
struct Model {
let colors: [UIColor]
let spacing: CGFloat
}
private var model: Model?
func setModel(_ model: Model) {
self.model = model
subviews.forEach { $0.removeFromSuperview() }
let views = model.colors.map {
let view = UIView()
view.backgroundColor = $0
view.cornerRadius = 3
return view
}
views.forEach { addSubview($0) }
setNeedsLayout()
}
// MARK: - Helpers
static func calculateSegmentWidth(total: Int, spacing: CGFloat, width: CGFloat) -> CGFloat {
guard total > 0 else { return 0 }
let totalSpacing = CGFloat(total - 1) * spacing
let availableWidth = width - totalSpacing
let segmentWidth = availableWidth / CGFloat(total)
return CGFloat.maximum(0, segmentWidth)
}
}
Step 4: Implement Layout Logic
Override the layoutSubviews
method to position the segments within the view. Calculate the width of each segment and set the frames of the subviews accordingly.
import UIKit
final class SegmentBarView: UIView {
// MARK: - Model
struct Model {
public let colors: [UIColor]
public let spacing: CGFloat
}
private var model: Model?
func setModel(_ model: Model) {
self.model = model
subviews.forEach { $0.removeFromSuperview() }
let views = model.colors.map {
let view = UIView()
view.backgroundColor = $0
view.cornerRadius = 3
return view
}
views.forEach { addSubview($0) }
setNeedsLayout()
}
// MARK: - Layout
override func layoutSubviews() {
super.layoutSubviews()
guard let model,
!model.colors.isEmpty else { return }
let segmentWidth = Self.calculateSegmentWidth(
total: model.colors.count,
spacing: model.spacing,
width: bounds.width
)
var offset: CGFloat = 0
for subview in subviews {
subview.frame = .init(
x: offset,
y: 0,
width: segmentWidth,
height: 6
)
offset += segmentWidth + model.spacing
}
}
// MARK: - Helpers
static func calculateSegmentWidth(total: Int, spacing: CGFloat, width: CGFloat) -> CGFloat {
guard total > 0 else { return 0 }
let totalSpacing = CGFloat(total - 1) * spacing
let availableWidth = width - totalSpacing
let segmentWidth = availableWidth / CGFloat(total)
return CGFloat.maximum(0, segmentWidth)
}
}
Step 6: Using the SegmentBarView
To use the SegmentBarView
, create an instance of the view and set its model with a few colors and spacing.
let segmentBarView = SegmentBarView()
let colors = [
UIColor.blue,
UIColor.blue,
UIColor.blue,
UIColor.lightGray,
UIColor.lightGray
]
let model = SegmentBarView.Model(colors: colors, spacing: 8)
segmentBarView.setModel(model)
Add segmentBarView
to your view controller's view and set its frame or constraints as needed.
view.addSubview(segmentBarView)
Conclusion
By following these steps, you’ve created a customizable segmented progress bar in UIKit. This segmented bar can be used to display progress or steps, providing a visual enhancement to your iOS applications. Feel free to extend and customize this component further to suit your app’s needs.
Thank you for reading until the end. If you have any questions, please feel free to write them in the comments.
If you enjoyed reading this article, please press the clap button 👏 . Your support encourages me to share more of my experiences and write more articles like this. Follow me here on medium for more updates!
Happy coding! 😊👨💻👩💻