Reputation: 3697
I am not sure (as I couldn't find anything) if this is the way progress views, work but when I have a value under 0.1, let's say 0.05, the progress view always shows up to 0.1, then anything above 0.1 works fine.
Is this normal?
Upvotes: 3
Views: 1955
Reputation: 189
I experimented a bit with that, and it turns out the minimum width of the progress indicator is twice its height.
As an exemple, say you have a UIProgressView that's 500px long and 50px high, any progress value below 0.2 will actually show a progress indicator that's 100px long. Indeed, 50px * 2 = 100px is the minimum width, for some reason .. So 0.2 * 500px = 100px is the minimum value that can be correctly displayed.
I would also recommend creating a custom progress view since it's quite a trivial component, and that sizing "feature" from Apple seems completely counter-intuitive to me.
I created a simple custom view using auto layout to make it easy to reuse:
class ProgressView: UIView {
var progress: Float = 0 {
didSet {
updateProgressView()
}
}
private let progressView = UIView()
private var progressViewWidthConstraint: NSLayoutConstraint?
init() {
super.init(frame: .zero)
clipsToBounds = true
backgroundColor = .lightGray
addSubview(progressView)
progressView.translatesAutoresizingMaskIntoConstraints = false
progressView.topAnchor.constraint(equalTo: self.topAnchor).isActive = true
progressView.leadingAnchor.constraint(equalTo: self.leadingAnchor).isActive = true
progressView.bottomAnchor.constraint(equalTo: self.bottomAnchor).isActive = true
progressViewWidthConstraint = progressView.widthAnchor.constraint(equalToConstant: 140)
progressViewWidthConstraint?.isActive = true
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func layoutSubviews() {
super.layoutSubviews()
updateProgressView()
}
func updateProgressView() {
let isCompleted = progress >= 1.0
progressView.backgroundColor = isCompleted ? .green : .blue
progressViewWidthConstraint?.constant = bounds.width * CGFloat(progress)
}
}
Upvotes: 0
Reputation: 58069
This is a side effect of using a UIProgressView
with a small width. Apple likely made this decision because they want to give clearly visible feedback to users that there is some progress going on - even if the view itself is short.
For a workaround, you can create a custom progress view with two views - one for the bar itself and one for the progress. After that, you can set the width of the progress view to the width of the bar itself, multiplied by the percentage progress.
You can use the cornerRadius
property of CALayer
for rounded edges.
let barWidth: CGFloat = 240
let barHeight: CGFloat = 2
let progress: CGFloat = 0.23
let progressBarView = UIView(frame: CGRect(x: 0, y: 0, width: barWidth, height: barHeight))
progressBarView.backgroundColor = .lightGray
progressBarView.layer.cornerRadius = barHeight / 2
progressBarView.clipsToBounds = true
view.addSubview(progressBarView)
let progressView = UIView(frame: CGRect(x: 0, y: 0, width: barWidth * progress, height: barHeight))
progressView.backgroundColor = .blue
progressBarView.addSubview(progressView)
Result:
Upvotes: 1