UIScrollView’s contentOffset precision

UIScrollView is featured prominently in the UIKit family and for good reason.
Being as awesome as it is, though, there are some quirks about it.

A prime example might be its contentOffset property.
There’re two ways to set the value of the contentOffset – either through the

method or directly using setContentOffset:.
If you use setContentOffset: or if you’ve specified NO for animated: , then the scrollViewDidScroll: delegate method of UIScrollView will only get called once, as opposed to animated:YES, where you get constant updates throughout the animation.
In all cases, though, passing a floating point value in the CGPoint for contentOffset gets rounded into an integer.
Let’s take a look at an example
Let’s say that we have this offset that we’d like to set it to our scroll view.

Well, if you query the contentOffset property after this method returns, you’ll be surprised to find out that the value is actually {4.0, 0.0}
According to Apple, this is intended behavior and it stems from the fact that you can’t have half of pixel be one color and the other half a different color.
We can actually specify such a case, though, we can make a view have a frame origin of 3.8 and iOS deals smartly with that by taxing the GPU a lot more with interpolating and antialising the content of the view, which usually comes out looking distorted and ugly, not to mention that it’s a big performance drain, especially on older devices.

With that out of the way – how can we make UIScrollView bend to our will and actually set its content offset to 3.8?

Easy, with the third way to set the content offset (I know, I lied) – as I mentioned setting the frame of a view really sets the  correct value, and UIScrollView is really just an UIView that does some magic with its bounds.

So setting the UIScrollView bounds achieves the desired effect.

And here we have our 3.8.

If you’d like to know why we might need that – stay tuned for more!
 

Leave a Reply

Your email address will not be published. Required fields are marked *