10

Sometimes you'll see a "clock wipe" animation in use. Something like this:

enter image description here

How would you achieve that effect in iOS?

(Note: This question is a "ringer." I wanted to share a technique for creating a clock wipe animation, but SO does not have a format for sharing tutorials, so the closest I can come is asking a question and then providing the answer. This is deliberate, and an attempt to share information that others might find useful.)

halfer
  • 19,824
  • 17
  • 99
  • 186
Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • 2
    I voted this question and its answer up, thanks for sharing this. You shouldn't have to justify answering your own question, it is actually encouraged in the help section : http://stackoverflow.com/help/self-answer – 2Dee Jan 08 '15 at 13:07
  • 1
    @2Dee, I *shouldn't* have to justify, but lots of people down-vote questions for silly reasons. Better to explain why I'm asking the question than to risk confusion. – Duncan C Sep 19 '17 at 13:30

1 Answers1

15

Answer:

You'd create CAShapeLayer and install it as a mask on your view's layer.

You'd then install an arc into the shape layer that spanned a full 360 degrees, and had a radius that was half the center-to-corner distance of your image. You'd give it a line width that was the same as the radius.

Finally, you'd create a CABasicAnimation that animates the strokeEnd property of the shape layer from 0 to 1.0. This would cause the shape to start out empty (image fully masked) and animate the mask as a "pie slice" that got bigger and bigger, until it was the full size of the image.

You can download a sample project on github that I wrote that shows working code for this animation, among other Core Animation techniques:

CA Animation demo on github


EDIT Update for Swift 5:

Ok, this thread is REALLY old. I tried to get the sample project to build and gave up fighting with Xcode after about 45 minutes. Too many settings are out of date with current project formats.

The clock wipe demo needed to be rewritten in Swift, so I just started over.

The new project can be found at this link: https://github.com/DuncanMC/ClockWipeSwift

Duncan C
  • 128,072
  • 22
  • 173
  • 272
  • 2
    Who down voted the answer? Granted, I posted this question specifically to post the answer, since SO does not have a tutorial format. I thought the clock wipe tutorial would be useful to others, since this is a pretty tricky technique to figure out using Core Animation. – Duncan C Mar 16 '14 at 02:48
  • Awesome post Duncan! Helpful as :) Thanks mate – Taylor Abernethy Newman Mar 24 '14 at 21:45
  • Hey Duncan, I am having problems with this working on device. iPhone 5s running iOS7.1, is there a change or something to the OS that may be effecting the CAAnimation? – Taylor Abernethy Newman Mar 31 '14 at 22:31
  • @TaylorAbernethyNewman, the project builds an iPad-only app. That's just because I wanted the screen real-estate for the different animations it does. It would be trivial to make it work on iPhone however. You'd just need to change the target device and create iPhone and iPad specific versions of the XIB file. – Duncan C Apr 01 '14 at 00:45
  • Hey Duncan, thanks for that, Sorry I wasn't clear enough, I have taken the framework and applied it to another iPhone app. The problem is obviously something to do with the porting on framework but Im struggling big time to find it... I have posted a question here.. http://stackoverflow.com/questions/22773951/cabasicanimation-not-working-on-device-iphone-5s #note that I have stripped down the original framework a bit too, this may be causing the problems.. hmm. Thanks for your time Duncan – Taylor Abernethy Newman Apr 01 '14 at 01:25
  • Hey Duncan, Did you know the mask animation doesn't work on 64-bit? Any ideas? – eric Apr 10 '14 at 01:19
  • Ok, I've figured some of it out.. iOS 64bit does not like your radian math (I actually use an inline, so i can think in degrees… sorry, not a math head) :-) So, If I replace "3*M_PI/2" with "M_PI * -90 / 180" and "-M_PI/2" with "M_PI * 270 / 180" it works fine in both 32 and 64 bit devices (and simulators) One nice thing about inlines is, it's easier to see the degrees. I would ctually use DEG2RAD(-90) and DEG2RAD(270). #define DEG2RAD(x) (x * M_PI / 180) #define RAD2DEG(x) (x * 180 / M_PI) But, again, thank you for this post, it has already come in handy! best, -eric – eric Apr 11 '14 at 19:52
  • It seems that the problem had t do with creating the Arc used by the mask. It seems that on 64 bit devices, CGPathAddArc doesn't work unless the clockwise parameter is YES. I switched it and it works correctly on 64 bit devices. This seems to be a bug in 64 bit versions of iOS. – Duncan C Jan 09 '15 at 02:19
  • does anyone here know how to achieve this in android? – vijaypalod Jul 17 '17 at 06:23
  • @mVJ, you could certainly do it using OpenGL. I don't know anything about animation on Android However. you might want first do some Google searching, and if you don't find anything, post a new question with an Android tag and link to this question to explain what you're after. – Duncan C Sep 19 '17 at 13:33
  • Can some one add swift version as well – Abhishek Thapliyal Jun 02 '20 at 04:23
  • 1
    @AbhishekThapliyal I'll try to find the time to rewrite it in Swift. Working with Core Foundation is actually *easier* in Swift, since it takes care of casting between CF types and Foundation types for you, and you don't have to deal with NSNumber and NSValue. – Duncan C Aug 23 '20 at 01:32
  • I just added a link to a Swift version of my project to the bottom of my answer. – Duncan C Aug 25 '20 at 17:15