9

I'm running a progress bar which updates every second. It needs to run for upwards of 300 seconds so the changes in the progress bar's 'progress' variable are on the magnitude of about 0.003 per second.

I've noticed a problem with low values of the 'progress' variable, though. Basically, there does not seem to be any difference between 0.09 and anything lower than that. So what ends up happening is when the progress bar is in the 0.0 - 0.09 range it doesn't show any visual changes even though the progress variable is changing. Another side effect is if I start the progress bar from 0.0 it immediately jumps to the image for 0.09 or so (and remains there until the real progress has passed that), which looks a little odd.

It's probably worth mentioning that this doesn't seem to be an issue anywhere else along the progress bar. It's able to move the bar 0.003 progress at a time everywhere else, including very near to 1.0.

I suppose it's not a huge deal, but I was wondering if anyone knew a way around this.

Thanks in advance.

Undo
  • 25,519
  • 37
  • 106
  • 129
  • What's the width of your progress bar? Are you on a Retina display? – Undo May 10 '13 at 23:11
  • 1
    It's width was 110, and I'm not able to see a difference between Retina and normal in the simulator at least. Based on your comment I tried making the width larger and the effect was a smaller "dead" range, but still significant with a 300 width progress bar. I believe I see the reasoning for longer bars having more accuracy, but it still doesn't make sense to me why the bar moves along just fine for every point after the small dead-zone at the start. – user2371691 May 11 '13 at 00:44
  • 1
    I got the exact same problem as you, more than 5 years later... What is this very strange bug? I can't solve it – Raphael Royer-Rivard Jan 07 '16 at 20:23
  • 1
    I'm having this exact same issue at the end of 2016 with Swift! I would have thought Apple would have addressed this issue by now, but I guess not. It's definitely annoying. – Pierce Nov 12 '16 at 00:22

3 Answers3

2

Try using 2 progress bars. One for micro and one for macro. Use the micro one to reflect a 0.1 range in the macro bar. That way you can show the finer movements.

sangony
  • 11,636
  • 4
  • 39
  • 55
  • Thanks for the idea. I gave it a shot, making the micro bar width 10 for a width 100 macro bar. Unfortunately the micro bar seems to be too small to register changes. To me, it looks exactly the same at 0.001 as it does at 1.0. Basically at this size it has one image for 0.0 (empty bar) and one image for everything above that (full bar). This is true both from looking at it in the storyboard and simulating it retina and non-retina. Unless I misunderstood. – user2371691 May 11 '13 at 00:54
  • I think you did misunderstand. I meant for you to use the micro bar to reflect every 0.1. Meaning you multiply by 10. For example, your current count is 0.452 you reflect 0.4 on your macro bar and reflect 0.52 on your micro bar. If your count increases from 0.452 to 0.482 your macro shows 0.482 but your micro now shows 0.82. When your count reaches 0.5 you reset your micro back to zero and start again... – sangony May 11 '13 at 01:13
  • 1
    Ahh, okay I see what you mean now! I was originally thinking you meant to overlay a smaller bar over the bigger bar to cover this "dead-zone" between 0 and 0.1, but I see that you mean actually having two bars separately (I think). I may have to go this route. Still, it bothers me that it's only in the 0 to 0.1 range that I cannot get the accuracy I need with one bar. Everywhere between 0.1 to 1.0 can register 0.003 size changes just fine for whatever reason. Thanks for your help. – user2371691 May 11 '13 at 01:25
2

I'm aware this post is essentially dead, but I came up with a way to deal with it that doesn't involve multiple UIProgressViews.

I decided to simply forget UIProgressView altogether and write a fake one leveraging UISlider instead. I removed the knob with [setThumbImage:[UIImage new] forState:UIControlStateNormal] and disabled user interaction. From here, I did everything else similar to how the UIProgressView works except obviously conforming to how the slider handles its tracking.

I also subclassed UISlider to utilize (CGRect)trackRectForBounds:(CGRect)bounds so that I could set the track height to look more like a UIProgressView.

Hope this helps someone else.

Stakenborg
  • 2,890
  • 2
  • 24
  • 30
1

I had the same issue few days ago, solved it by removing the UIProgressView and using two UIView instances and UIViewPropertyAnimator instance.

Basically the first view represents an empty progress, it should take the width of your progress bar, second view represents the progress movements, it should take zero width initially, it should be above the first view, and both views should have different colors. Maybe a light gray color for the empty progress view and dark gray color for the actual progress view.

Then, when your progress starts, increase the width of the second view, so it will overlay the empty progress view.

Use UIViewPropertyAnimator to make the animation, it provides easy and useful built-in functionalities to handle the animation smoothly, for example you can pause the animation and resume it.

Ziad Kamel
  • 37
  • 1
  • 6