Search code examples
objective-ciosopengl-escore-graphics

Fastest possible Apple Style Flip Counter in native code on iOS


I'd like to mimic an Apple style flip counter on iOS.

Specifically, this thing is going to be FLYING FAST. It's not going to be an alarm clock, think player high-score where you are racking up points chunks at a time. The counter may jump from 0 to 100, to 5000, it will not increment sequentially, but when it does increment it will animate to the next number at a nice clip and it's going to be jumping to the next target value in a second or two. It will not have a set number of digit places either, it can count from 0 to 2,000,000 if it wanted to. Like a player high-score, you don't know what they will end up getting. Since it can't be negative, theoretically maximum would be UINT_MAX

I did some searching, and I found a couple of great resources, neither of which seems to me like the correct approach.

This is a js/css approach the theoretically could run inside a UIWebView:

And this article explains how to do page turning in Core Animation. It's detailed enough, but it seems to me like it's missing some key components, and would cause touches to get ignored on the UI while it's flipping.

Now, after reading these I've got some different ideas on how to do it on my own, trying to weigh the pluses and minuses of each approach:

1) Load up the html counter whole-sale in the UIWebView.

  • Apparent benefits: possibly tons of code reuse, quick and dirty
  • Apparent downsides: the overhead of a UIWebView and constant calls to stringByEvaluatingJavaScriptFromString from the host app which has the next number just seems silly

2) Create a custom sprite sheet and use core animation

  • Apparent benefits: native code, seems like it would be a less fugly approach than using the web view
  • Apparent downsides: creating a custom sprite sheets at this point seems a bit pointless in the face of custom drawing since I'm already creating a view with custom drawing anyway. Seems like the only way to get it to perform well would be to draw images to sublayers rather than using UIImageViews

3) Render text/rounded rects with Core Graphics

  • Apparent benefits: 100% native code solution, no images
  • Apparent downsides: boatloads more code that having some UIImage instances. Don't really know if I can get the right look I'm after without the images

4) Render the whole thing with OpenGL ES 2.0

  • Apparent benefits: complete control over rendering, possibly best performance
  • Apparent downsides: seems to me like I would still probably need some images to bind to textures, probably piles more code than core graphics rendering in #3

On the one hand, I can rationalize it and say the animation is only going to last a half a second or a second, so the best thing to do is to just fake it somehow with blurry images and not actually animate anything. On the other hand it seems to me this is precisely what Core Animation + Core Graphics was designed to do well, and I ought to use them.


Solution

  • Ended up doing the drawing with images using image sprites.

    code here https://github.com/reklis/flipcounter