Skip to content
This repository has been archived by the owner on Jan 19, 2022. It is now read-only.

Pixelated progress bar #4

Closed
DeepAnchor opened this issue Oct 27, 2016 · 20 comments
Closed

Pixelated progress bar #4

DeepAnchor opened this issue Oct 27, 2016 · 20 comments
Labels

Comments

@DeepAnchor
Copy link

Hello,

Thanks for making this project! I'm having some issues with the way the progress ring is rendered. I'm embedding the progress ring into a TableViewCell and when it first loads, it shows up pixelated like this:

unclicked table cell

Strangely, after clicking it, it then renders nice and smoothly:

after clicking the table cell

This is some minimal test code for initializing the TableViewCell, using Cartography for autolayout constraints .


 override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        let progressRing = UICircularProgressRingView(frame: CGRect(x: 0, y: 0, width: 50, height: 50))

        progressRing.setProgress(value: 39, animationDuration: 2.0) {
            print("Done animating!")
        }

        self.contentView.addSubview(progressRing)

        constrain(progressRing) {p in
            p.center == p.superview!.center
        }
    }

I'm not sure that it has anything specifically to do with your library since I can't seem to reproduce it from your sample app, but do you have any idea what could be causing this?

There are a bunch of stackoverflow issues that say it might have something to do with CALayer and the contentsScale property, but I don't have enough experience with CALayer to know whether that's the case.

@luispadron
Copy link
Owner

Hmm that's strange, I've never used Cartography before or tested with this project so that may be another issue.

Could you try to call setNeedsDisplay() after constraining the view

Example:

constrain(progressRing) {p in
    p.center == p.superview!.center
}

progressRing.setNeedsDisplay()

This will cause the view to be redrawn completely, and hopefully it does something to help.
Again, I've never used Cartography for autolayout so this may be the problem.
However if it's not I'll look into those stackoverflow issues you mentioned.

Thanks for the feedback!

@DeepAnchor
Copy link
Author

I added progressRing.setNeedsDisplay() and it produces the same behaviour.

Actually I should have left the autolayout code out of that snippet as it seems to make no difference either when I remove it. I feel like it has something to do with the whole anti-aliasing thing when the CALayer is put into a table view cell.

@luispadron
Copy link
Owner

Alright, thanks for the quick reply.

I will take a longer and closer look at this as soon as I get out of school today.
So you're saying to reproduce, just drop the view in a tableview cell?
Are your cells dynamic or static?

@DeepAnchor
Copy link
Author

ok cool! Yeah, just drop the view in a tableview cell. I'll try to get a minimal repo up to reproduce the issue. I think the cells are dynamically sized .

@DeepAnchor
Copy link
Author

i've made a quick repo demonstrating the issue here

@luispadron
Copy link
Owner

luispadron commented Oct 27, 2016

Thanks for the test project.
To be honest didn't notice a huge issue with pixelation, but this may be because I am on a 5k iMac running via simulator and don't have any retina devices to test on.

I did notice that when I removed the draw function from UICircularProgressRingView the view became extremely blurry, I also know how many weird issues cells have with custom drawn views. So I went and set some scale factors to the custom layer. Hopefully this should fix the issue you had, keep me updated.

Run pod update to get the latest changes

Release: v1.1.2

@DeepAnchor
Copy link
Author

Unfortunately it didn't work =(

I'm seeing the pixelation in simulator, iphone as well as my retina MBP. I think this issue is more systemic to ios/UIkit than anything specific to your library, so i'm going to close this issue for now. If I discover a fix i'll report back.

Thanks for your help!

@luispadron
Copy link
Owner

I wish I could help further its just that the repo you provided doesn't demonstrate the level of blur you experienced in the screen shot.
I only saw minor jaggies and blur.

@DeepAnchor
Copy link
Author

Yes that is weird. But your iMac does probably have an unusually high pixel density =P
Would it be possible for you to post a screencap of what it looks like on your screen?

@luispadron
Copy link
Owner

After more testing and messing around I do see the issue, and I see whats actually wrong now.
Whats happening is when calling setProgress in cellForRow, the CALayer I am using gets redrawn because it listens and updates the view according to the value of the progress bar, this allows for fluid animations. However, when inside a tableview cell something weird is happening which is causing the Layer to draw over itself.

You can test this out by removing setProgress from cellForRow and adding a button to the ui and when clicking the button then call setProgress. You will see how the layer and text gets drawn over itself, this is odd, but something I have noticed while testing another view I was working on.

At least I know what the issue is now, will update if I find a fix.

@DeepAnchor
Copy link
Author

You can test this out by removing setProgress from cellForRow and adding a button to the ui and when clicking the button then call setProgress. You will see how the layer and text gets drawn over itself, this is odd, but something I have noticed while testing another view I was working on.

Your explanation of what is happening makes sense. I just tried this out and it renders beautifully! But yeah, I do wonder what is causing it to draw over itself.

@luispadron
Copy link
Owner

Well not a fix exactly but, for now if you'd like to use the view inside a tableview cell.

Something that has worked and I have tested is to create the TableViewCell using interface builder. Again, not sure why this works.

But if you create a TableViewController inside interface builder and create a custom TableViewCell file, add the view as a subview via interface builder and call setProgress the view draws perfectly fine and you are able to use dynamic cells. For some reason adding the view as subview programmatically causes issues with it's behavior.

I will keep this issue opened since this is a bug, and will keep looking for an actual solution or explanation.

Let me know if you'd like sample code for what I just said

@luispadron luispadron reopened this Oct 28, 2016
@luispadron luispadron added the bug label Oct 28, 2016
@DeepAnchor
Copy link
Author

Hmm that's very odd indeed. Just to add another data point to your previous comment about the animation drawing over itself, I noticed that when I have multiple progress bars, setting two or more progress bars simultaneously causes the animation to overlap. GIF to demonstrate:

The topmost progress bar's value is set in isolation first. Everything works fine.

The middle and bottom progress bars' values are set almost simultaneously. There you can see the animation drawing over itself.

@luispadron
Copy link
Owner

And these are inside tableview cells correct?

@DeepAnchor
Copy link
Author

DeepAnchor commented Oct 29, 2016

yes these are inside tableview cells and added programmatically

@luispadron
Copy link
Owner

yeah ive noticed too many weird things with putting custom views inside tableview cells programmatically. There has to be some sort of difference with how those cells get generated between IB and programmatically, ill try and see if I can fix this weird behavior but it might take some time since im not extremely familiar with all the inner workings of cells (still a newb)

@DeepAnchor
Copy link
Author

yeah fair enough, I'm pretty much on the same boat as you. I'll keep digging also -hopefully we will be able to get to the bottom of this!

@DeepAnchor
Copy link
Author

@luispadron ok I finally got back round' to this and I think I solved the issue. When you make the progress ring's background colour clear (i.e - progressRing.backgroundColor = UIColor.clear), everything works perfectly!

Perhaps we should change UICircularProgressRingView so that this is the case by default?

luispadron pushed a commit that referenced this issue Dec 19, 2016
- Default background color for view is now UIColor.clear
- Update CHANGELOG
- Update podspec to 1.1.7
@luispadron
Copy link
Owner

@DeepAnchor Awesome! Thanks, I don't know why I didn't think this may have been the issue.

Just tested and it seems to not be pixelated anymore.

Changes are up in release 1.1.7

@shaeelabbas
Copy link

Hi @luispadron @DeepAnchor I have set the backgroundColor to UIColor.clear however I am seeing that there is still some pixelation and sort of noise around the borders of the circular ring, as you can see in the image I am sharing, if you look carefully

https://ibb.co/PCyKd7C

Was this issue resolved in any other way? Thanks?

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants