in iOS, tutorial

Creating a custom button (with animated content!)

As I am getting closer to the releasing date of my first app (let’s create some hype :P), I want to start going through some difficulties I have found. One of them was how to create a button with animated content. I wanted to provide my app with some kind of funny/playful effect. For a better understanding I have created this gif straight from the screen. Keep reading if you want to know how I have achieved this result!

zzButton

Like any other good dev, when I had the idea in mind but not in Xcode, I looked into the sanctuary of code: stackoverflow. From there, I extracted 2 answers, but I am still not 100% sure if what I am doing is right, so if you are reading this and realize this is rubbish… please let me know. I would like to say “guys, I have done some tests with Instruments and this one is better than the other one performance-wise”, but I haven’t, yet.
It works for me, but maybe there is a 3rd and supreme answer to my request. Both of these options are based on the same principle “add a view at the top of the button”. In this case, I will add as a view 2 simple UILabels, but I have tried with an UIImage and works exactly the same. There is another example at the bottom of this post using an UIImage.

a) Custom button + content

Straight forward option. In fact, is the one I am using at the moment and I am still thinking if I should move to the second option. Let’s get started. Drag a button to your view (or add it as a subview programmatically) and choose a custom type.
I have used this image for the button. I know, it is so easy to draw it with code! Let’s wait for the second option to do that.

Screen Shot 2013-04-23 at 18.16.02

Now drag 2 UILabels inside the button (in this case 2 “z” letters, one slightly bigger than the other). Let’s create 2 IBOutlets, I have called them zUP and zDown.

And now is when the magic comes :D. I have used CAAnimation for achieve the “up&down” effect, although it can be done with [UIView animateWith…].

Here is the code, I have created my own method and then it is easy to add it to any existing view.

That’s it for the animation. Easy peasy! I think every line of code is pretty understandable. The only bit of code I did hesitate was the repeatCount value. The HUGE_VALF is defined in math.h as 1e50f which is pretty good for using as an infinite number.

For add it two any view (in this particular case, to our 2 UILabels) just add a line of code similar to this:

I have add this in my viewWillAppear, chained after some other transition animation effect.

b) Custom View + content

Some days ago I mentioned Drawscript.
I know this is a super-easy path, but here is an screenshot of the plugin in action (using illustrator).

Screen Shot 2013-04-22 at 11.23.51

As you can see, after selecting the path or paths we want to turn into code, we just need to click ‘generate’. Copy and paste. This is the code Drawscript has generated for the selected path:

To be honest… I don’t like this code for this particular case. Drawscript generates the code for exactly what we have drawn (so be careful with dimensions!). This means we can’t resize the button, we will have to use it always as it is (43×43 px). So for making this view to be reusable it is better to do something like this (much easier as well):

This will produce exactly the same result, but when we create an instance of our VBFZzButton, we can set any frame we want (not only 43×43).
Having said that, we need to be notified when the user taps the view. For doing it we are going to use a very cool feature, a delegate. When I started programming for iOS I was a bit scared about learning how to use delegates. I thought they would be difficult and advanced hardcore stuff, but once you make one… you fall in love with them.
We will use them anytime a class needs to send a message back to its owner (if the owner conforms to this class’ protocol).
Here is a simple step by step list you need to follow to create a simple callback method to get notified using delegates:

  1. Define a @protocol in .h (or you can always create a new Objective-c protocol class file).

  2. Add to your protocol any method you want to send to it’s owner (they can be @required or @optional).

  3. Declare a public delegate

  4. In the implementation file, send to self.delegate the methods you defined in your protocol (where convenient).

  5. Declare the owner class as a delegate

  6. Do whatever you want inside the protocol methods

Numbers 5 and 6 are implemented in the owner class.

Let’s see this in action!

Lets move now to the owner of this class, in my case “InitialViewController”.

And this is it. As easy as that. For adding the “Z”s subviews to the button, just add 2 UILabels programmatically and use same animations as Option 1.

This is another example I have used this trick for:

QMark

In this case though, the tilt value is set by the orientation of the phone. Not sure If I will use it in the final version… But here we will see how to do it in a future post. Stay tuned :D

I hope you have enjoyed, and please let me know if I can improve anything up there.

Spotted error – Thanks to @rcabamo for spotting an error in the code. I had declared the delegate as strong, and it should be weak in order to avoid retain cycles.

Leave a Reply