Drop me an email if you'd like to hire me (part time) or learn more about what I do. You can read about my experience and references on LinkedIn.
iOS: Prototyping button-like control with nice animations
I browsed dribbble.com again and found cool UI control. Unfortunately I cannot find the resource again on dribbble -
It just disappeared and I do not have any link to it. Anyway, here is the final effect very similar to what I
The logic behind the control is easy to understand. The button has 4 states.
Begin - Blue button with just Submit title. You can push it down and it
will nicely be pushed deeper and colors will be inverted
Loading - After button is pushed down and then released it gets back to the
previous appearance and animates to show a spinner. This is good time to do
e.g. network requests, submitting a form, etc.. - Please notice how button dimension
is changing to create circle with the spinner - This is why I like it.
Finish with success - After you did your work and everything finished with
success, you can change to this state to show some success message and style
the button little bit differently. Here I used darker blue.
Finish with failure - If something went wrong you can style the button to
indicate that operation failed. A bit later state of the button goes back to
Begin so you can tap it again and re-try an operation.
Not sure whether this is designed in an optimal way or not. Probably something
could be simplified. If you find such thing, I’d be glad to know it.
Schema explained below.
1 - Main view for the control.
2 - I called this placeholder view but this is not the correct name. This view
have constraint that specifies width of the control and do not have any other
subview in it. Every subview is added to 1. This view is hidden.
3, 4, 5 - Each of these represent another state of the control.
The first one is label presented for Begin state, the second contains spinner
and the third contains success/failure message. Each of these has also the same
height as the 1 - It ensure that subviews of 3 - 5 are correctly centered
both vertically and horizontally while presented on screen. Each of these are horizontally
centered in 1.
5 - This view does not have constraint to the bottom of the 1.
6 - This is constraint between top of the 1 and top of the 3.
It allows to easily scroll subviews during state changes.
7 - As mentioned above, this is a width constraint of the control.
The control has 8 properties that define colors of texts and background
for a specific appearance style - Normal, Pressed, Disabled, Success, Failure.
When state changes view appearance is changing.
Added listeners for TouchUpInside, TouchUpOutside, TouchDown control events,
so style of tapping/pressing button and releasing it can be easily updated.
Here are two animations that changes scale of a button, so it imitate pushing it and
creates some depth on the screen.
The next important thing is a method which is responsible for animating state
Let’s take a look what’s going on here.
At the beginning we need to obtain container with a label/spinner that will
be presented after state did change.
The next two lines are interesting.
I noticed this:
Changing text and animating entire control (scrolling its content) caused that
label (for Final state) was going up-left or up-right depending whether text
was changed to long or short.
This was caused because container with label was updating its layout in the same
pass as entire control was shifting its subviews.
Adding these two lines forces another quick pass on the current loop (main thread)
so UI gets refreshed and label is correctly positioned. In effect, when animating
change state, you can see that longer label is nicely animated keeping its centered
This should better illustrate the issue. Notice how long label on right is
shifting while presenting.
Next thing is to set new width of the control. We need to take width of a subview
inside the container and add some margin. The margin is calculated to create
a circle when spinner is presented. Labels and spinners have the same leading
and trailing distances to the control leading and trailing edges.
Next lines of code just changes color of the labels and the background, so
In case when new state is Finish with failure there is CATransition animation
added to the control’s layer, so it nicely animates state change to Begin with
a fade effect.